OJ上有这样一道题:
题目要求连带着空格符号也读取进来,因此必须要使用getline()函数。
C++中本质上有两种getline()函数:
第一种:在头文件<istream>中,是iostream类的成员函数。
第二种:在头文件<string>中,是普通函数。
第一种: 在<istream>中的getline()函数有两种重载形式:
istream& getline (char* s, streamsize n );
istream& getline (char* s, streamsize n, char delim );
作用是: 从istream中读取至多n个字符(包含结束标记符)保存在s对应的数组中。即使还没读够n个字符,如果遇到delim 或 字数达到限制,则读取终止,delim都不会被保存进s对应的数组中。
第二种: 在<string>中的getline函数有四种重载形式:
istream& getline (istream& is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
istream& getline (istream& is, string& str);
istream& getline (istream&& is, string& str);
用法和上第一种类似,但是读取的istream是作为参数is传进函数的。读取的字符串保存在string类型的str中。
函数的变量:
is :表示一个输入流,例如 cin。
str :string类型的引用,用来存储输入流中的流信息。
delim :char类型的变量,所设置的截断字符;在不自定义设置的情况下,遇到默认值“换行符”(换行符每种系统不一样,Windows下是”\r\n”,Linux\Unix下是”\n”,Mac下是”\r”),则终止输入。
实际上我们使用的如:
getline(cin, s);
这样的写法,实际上是在使用第二种函数,传进去的参数第一个表示输入流“cin”,第二个则是存储输入流中的流信息,第三个参数没有,默认到’\n’中止输入。在Windows系统下,我们输入一串字符后按下回车,实际上被存储为一串字符+”\r\n”,而在Linux系统下,系统默认的“换行”则是”\n”。
问题是,当一道题被输入OJ后,它对应的案例采用的是二进制法传输,那么也就保留了老师在输入OJ时留下的“换行符”,这个换行符是哪一种呢?很大概率是”\r\n”,因为老师有很大可能用的是Windows系统进行输入的。
问题又来了,OJ是基于Linux环境搭建的网站,OJ的编译器也是Linux平台上的编译器,编译器会自动去判断当前的系统使用的是哪一种“换行”,那么编译器在编译的时候,由于是在Linux平台下运行,因此getline()的第三个参数便默认为”\n”,因此在处理的时候,会把”\r”当作字符串的一部分保留下来,后边的”\n”则被当作一行结束的标志被删除。由于老师是在Windows下输入的案例,连带着把本不该出现的”\r”也保留在了OJ的案例里,因此我们的程序在最后实际上拿到的是案例字符串+”\r”,而我们想要的只有字符串,因此我们必须要把最后出现的”\r”删除。事情到现在就好办了,只是删除最后一个字符”\r”,只需加入以下代码即可:
string s; getline(cin,s); if(s[s.length()-1]=='\r') //判断最后一个字符是否是留下的"\r" { s=s.substr(0,s.length()-1); //将s的最后一个字符删掉 }
搞定!下一题!