In function for different processing of input buffer
今天在写基于KMP的计算字符串匹配次数的时候,处理casen和字符串又犯了当年刚学C++时的错误,究其原因就是没有仔细读函数的说明,尤其是这几个输入函数或者cin对于输入缓冲区的处理。
- cin
cin>>n,一般如果敲入一个\n或者space或者\t来使他识别出前面是需要输入的整数,cin居然会把这个delim符留在inputbuffer里,保留!!另外有一点要注意,任何输入函数只要inputbuffer里面有东西就会优先抽取
这里的数据,等到空了,才会请求或抽取键盘的输入
2.string::getline(istream& cin, str,delim)
这里cin对应的形参是istream类型,iostream, istringstream, ifstream等等都是继承了它的,因此文件流,字符串流,控制台输入流都是可以调用的
这里为了强调,把这段文档说明写在这里,
If the delimiter is found, it is extracted and discarded, i.e. it is not stored and the next input operation will begin after it.
这里delim其实是包含了默认的\n的,所以看到了么,他会抽取再丢弃作为字符串抽取结束的标志!!丢弃\n!!
另外std::getline() string这个函数是重载了istream::getline的
3.istream::cin.getline(str,n,delim)
这里cin对应的也是istream,调用同上。本质区别就是这个是C字符串的输入函数
The delimiting character is the newline character (‘\n’) for the first form, and delim for the second: when found in the input sequence,
it is extracted from the input sequence, but discarded and not written to s.
由于C的,自然特殊的结束符要考虑,这里参数n是包含\0,所以函数全称是抽取长度为n-1的字符串或者不到n-1但是遇到delim,然后str加上\0,同时将delim(如果出现的话)丢弃,也即删除出input buffer
A null character (‘\0’) is automatically appended to the written sequence if n is greater than zero, even if an empty string is extracted.
好的现在总结已经非常清楚了估计,以后不能再犯这个错误了。
另外今天有个神奇的输入问题,就是http://www.cnblogs.com/A-Song/archive/2012/01/29/2331204.html
#include <iostream>
using namespace std;
int main()
{
char str[8];
cin.getline(str, 5);
cout<<str<<endl;
cin.getline(str, 5);
cout<<str<<endl;
return 0;
}
输入abcdefgh\n 居然程序结束,而且第二个空。后来问了大神,才知道cin的一个badbit被置位了,例如也即这种属于抽取字符串失败了,后面也没必要再读了,认为也是错误的,所以只要没有抽完第一个串的所有字符,
就认为出错了,badbit值1,后面读取,由于char[] 的缘故,自动赋\0, 而其他的类型都不会。。。。while(cin>>x)… 如果要读入整数,却输入字符,就置failbit为1,cin也是返回false了。 cin确实很复杂,所以慢慢总结,
今天输入这样的数据:
3
A 1 1
类似这样的数据,然后发现要一直用scanf之类的,尤其是大量输入的时候cin会非常慢,因为需要凑齐到缓冲器再输入到内存中。
scanf("%d");
scanf("%c%d%d")
类似这样的写法是不能过的,因为输入3之后有一个\n,然后还在缓冲区,然后抽取%c遇到\n, 是一个whitespace(include \t \n space这三种),于是抽取字符变成空的,同时后面的抽取一个非nonwhitespace,于是后面都乱,具体为啥是个野值还不清楚。
一开始以为用个变量抽取掉%c
scanf("%d");
scanf("%c");
scanf("%c%d%d");
后来发现瞿神代码是这样的
char s[5];
scanf("%d");
scanf("%s%d%d");
看了scanf文档,似乎char和char* 好像都是遇到whitespace就结束,但是瞿神说scanf(非%c) 和cin 如果遇到whitespace就会智能的跳过,我一直怀疑,因为之前getline好像inputbuffer里的
whiltespace是会读取然后出错的,后来实验果然瞿神是对的。于是发现只是getline会读取任何whilespace导致string出错,但是cin和scanf处理字符串都不会因此出错,
也即
cin>>n;
cin>>str;
是对的,但是
cin>>n;
getline(cin,str);
是会出错的,因为cin scanf对于输入给字符串可以跳过whiletespace,getline则不会导致出错。