0

在下面打印的程序中,gets() 的问题是它仅第一次获取数据,并且每次后续调用都会导致 null,因为输入数字时 istream 中的杂散 \n 留下了。

main()
{
    char name[20];
    int number;
    for(int i=0;i<5;i++)
    {
        printf("enter name");
        gets(s);
        printf("enter phone number");
        cin>>a;
    }
}

现在我的问题是,为什么当我使用scanf()or时发生的情况不一样cin?我的意思是 cin 和 gets() 获取它们的值的方式有什么区别,这使得 cin (和 scanf )能够成功地离开那个流浪\n但不是gets()

PS:我知道 fgets(),gets() 已被弃用及其不良影响,通常也不使用它。

4

3 回答 3

2

您正在混合面向行的输入和面向场的输入。gets(),等函数fgets()读取。他们不一定关心行的内容,但他们会阅读整行(假设在某些情况下有空间)。

cin像'>>运算符这样的面向字段的输入scanf()不关心行,他们关心字段。像这样的电话scanf("%d %d %d", &x, &y, &z);不在乎它们是在同一行还是在 3 个单独的行上(或者即使您留下空白行)。

这些面向字段的输入函数往往会留下会混淆面向行的输入函数的换行符。一般来说,您应该避免将两者混合使用,如果您想两者兼而有之,阅读该行然后使用sscanf()stringstream从中进行基于字段的输入通常很有用。这也使得从错误输入中恢复更容易,您不必担心是否有额外的'\n'字符等待您的下一个输入函数。

于 2012-06-11T20:06:54.030 回答
1

scanf并且cin >>都读取由空格分隔的字段,并忽略前导空格。现在 whitepsace 是空格、制表符和换行符,因此输入中的额外换行符不会打扰它们。更重要的是,在阅读完某些内容后,他们不会阅读以下任何空白,而是将其留在输入中以供下一次读取。

现在scanf,您可以通过在格式字符串末尾使用空格来明确告诉它尽可能多地读取(并丢弃)空格,但这对于交互式输入效果不佳,因为它会一直尝试读取直到它得到一些非白色空间。因此,如果您将循环的结尾更改为:

printf("enter phone number");
scanf("%d ", &a);

输入电话号码后它似乎会挂起,因为它在等待您输入一些非空格,最终将被下一个循环迭代读取为下一个名称。

你可以使用 scanf 做你想做的事——阅读和使用电话号码后面的文本直到换行——但它并不漂亮:

scanf("%d%*[^\n]", &a); scanf("%*1[\n]");

您实际上需要两次 scanf 调用来使用换行符以及可能在行上的任何空间或其他杂物。

于 2012-06-11T21:40:57.153 回答
0

gets()与 不同fgets(),应该用空字符替换终止换行符。
这是来自gets()手册页:

get() 函数应从标准输入流 stdin 中读取字节到 s 指向的数组中,直到读取到 a 或遇到文件结束条件。任何一个都应该被丢弃,并且在读入数组的最后一个字节之后立即放置一个空字节。”

虽然fgets()将通过换行符不变:

fgets() 函数应从流中读取字节到 s 指向的数组中,直到读取 n-1 个字节,或者读取 a 并将其传输到 s,或者遇到文件结束条件。然后字符串以空字节终止。

因此,您的实施似乎不符合标准……我的工作如前所述。

于 2012-06-11T20:11:04.620 回答