Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当输入是int和string的混合时,Scanf读取两次_C_String_Loops_Io_Scanf_Do While_While Loop - Fatal编程技术网

当输入是int和string的混合时,Scanf读取两次

当输入是int和string的混合时,Scanf读取两次,c,string,loops,io,scanf,do-while,while-loop,C,String,Loops,Io,Scanf,Do While,While Loop,我试图从stdin读取一个整数,然后逐字符读取字符串: #include <stdio.h> int main(int argc, char const *argv[]) { int T,N,i; scanf("%d",&T); while ( T-- ) { scanf("%d",&N); printf("N is %d\n",N ); char ch = getchar();

我试图从stdin读取一个整数,然后逐字符读取字符串:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int T,N,i;
    scanf("%d",&T);

    while ( T-- )
    {
        scanf("%d",&N);
        printf("N is %d\n",N );
        char ch = getchar();

        while ( (int)ch != '\n')
        {
            ch = getchar();
        }

        // printf("Outside.\n");
    }
    return 0;
}
但在运行时,我会得到如下输出:

./COOMILK < input.txt
N is 7
N is 7
N is 5
N is 5

为什么要两次读取相同的值?

想想用户在做什么。他输入一个数字然后呢?他点击进入!这就是新行,它被插入到stdin缓冲区中,等待程序读取

因此,当你尝试读取字符时,从之前存储的换行符会得到,这解释了你所看到的行为

不需要强制转换ch来检查内部循环中的换行符。此外,内部循环作为一个循环会更好

返回一个int,而不是char,所以我将对此进行更改,并考虑EOF。阅读更多信息

正如Ed Heal指出的,您可以利用to的返回值来确保它已读取整数

我想把你的观点改为:

输出:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out < input.txt 
N is 7
cookie milk milk cookie milk cookie milk
N is 5
cookie cookie milk milk milk
N is 4
milk milk milk milk
N is 1
cookie

想想用户在做什么。他输入一个数字然后呢?他点击进入!这就是新行,它被插入到stdin缓冲区中,等待程序读取

因此,当你尝试读取字符时,从之前存储的换行符会得到,这解释了你所看到的行为

不需要强制转换ch来检查内部循环中的换行符。此外,内部循环作为一个循环会更好

返回一个int,而不是char,所以我将对此进行更改,并考虑EOF。阅读更多信息

正如Ed Heal指出的,您可以利用to的返回值来确保它已读取整数

我想把你的观点改为:

输出:

Georgioss-MacBook-Pro:~ gsamaras$ gcc -Wall main.c 
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out < input.txt 
N is 7
cookie milk milk cookie milk cookie milk
N is 5
cookie cookie milk milk milk
N is 4
milk milk milk milk
N is 1
cookie
用一些聪明的东西?!使用-请参阅手册页-您可以将代码简化为:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int T,N,i;
    if (scanf("%d\n",&T) != 1) { // Notice the new line
       // Do so error reporting
       return 1;
    }

    while ( T-- )
    {
        if (scanf("%d\n%*[^\n]\n",&N) != 1) { // Please see scanf for an explaination
           // Do some error reporting
           return 1;
        }
    }
    return 0;
}
编辑

scanf格式说明

%d读整数 \n-读取新行 %*[^\n}-阅读除新行以外的任何内容,并丢弃结果 \终于读到了一行新词 通过一些巧妙的?!使用-参见手册页-您可以将代码简化为:

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int T,N,i;
    if (scanf("%d\n",&T) != 1) { // Notice the new line
       // Do so error reporting
       return 1;
    }

    while ( T-- )
    {
        if (scanf("%d\n%*[^\n]\n",&N) != 1) { // Please see scanf for an explaination
           // Do some error reporting
           return 1;
        }
    }
    return 0;
}
编辑

scanf格式说明

%d读整数 \n-读取新行 %*[^\n}-阅读除新行以外的任何内容,并丢弃结果 \终于读到了一行新词
请阅读手册页-记下返回值还有,为什么在与@lpares12比较时将ch转换为int?@lpares12否则不起作用。请阅读手册页-记下返回值还有,为什么在与@lpares12比较时将ch转换为int?@lpares12否则不起作用。scanf%d,&n;->您应该检查返回值以确保它已读取一个整数返回一个int,而不是char-需要考虑EOFThank you@EdHeal的注释。我更新了我的答案是否正确?收回你的否决票也可能是一个积极的信号。=你没有检查scanfscanf%d的返回值,&N;->你应该检查返回值to确保它已读取一个整数,返回一个int,而不是char-需要考虑EOFThank you@EdHeal的评论。我更新了我的答案是否正确?收回你的否决票也可能是一个积极的信号。=你没有检查scanfDetail的返回值:\n不仅读取新行,还将读取0或更多的白色spaces包含新行。@chux-很好-但在读取%*[^\n]之后,它还能是其他内容吗?1否,但在%d之后也使用了“\n”。2扫描%d的意外结果\n%*[^\n]\n、 &n是指函数在123\nabc\n之后输入一些非空格后才会返回。若要按照OP的指示读取行,而while\n则最好使用fgets as scanf,这是一个错误的工具。详细信息:\n不仅读取新行,还会读取0或更多的空格,包括新行。@chux-很好-但在读取%*[^\n]之后可以是其他内容吗?1否,但“\n”也在%d之后使用。2 scanf%d\n%*[^\n]\n、&n的意外结果是,函数在123\nabc\n之后输入一些非空白之前不会返回。若要按照OP的意思读取行,而\n最好使用fgets,因为scanf是此作业的错误工具。