使用fgets
to read in a line 更简单,更健壮:
if (!fgets(buff, 28, stdin))
{
// reading failed, do appropriate error handling
// we're just exiting here
exit(EXIT_FAILURE);
}
// We have successfully read in a line, or at least the first 27
// characters of the line. Check whether a full line was read,
// if it was, whether the line was empty
size_t l = strlen(buff); // <string.h> must be included
if (buff[l-1] == '\n')
{
// a full line was read, remove trailing newline unless
// the line was empty
if (l > 1)
{
buff[l-1] = 0;
}
}
else
{
// the input was too long, what now?
// leave the remaining input for the next iteration or
// empty the input buffer?
}
printf("%s\n",buff);
它不起作用,scanf("%s",buff)
因为大多数scanf
转换都会忽略前导空格:
输入空白字符(由isspace
函数指定)将被跳过,除非规范包含[
、c
或n
说明符。
因此,如果用户输入一个空行,则scanf
忽略该输入,除非其格式是异常之一。
您可以改用scanf
字符集格式,
scanf("%27[^\n]%*c", buff);
读取所有字符直到换行符(但仅限28 - 1
于此处以避免缓冲区溢出),然后使用换行符而不存储它(转换说明符*
中的%*c
禁止赋值),这将处理完全由空格组成的非空行,其中%s
转换不会。但是,如果输入的第一个字符是换行符,则%27[^\n]
转换失败(感谢chux引起注意),换行符留在输入缓冲区中,如果换行符不是,后续使用该格式的扫描也会失败从输入缓冲区中删除。
scanf
据我所知,使用有点健壮(但丑陋;并且不处理太长的输入)循环需要在扫描之前检查换行符,例如
for(int ct = 0; ct < i; ++ct)
{
int ch = getchar();
if (ch == EOF)
{
// something bad happened; we quit
exit(EXIT_FAILURE);
}
if (ch == '\n')
{
// we had an empty line
printf("\n\n");
}
else
{
// The first character was not a newline, scanning
// with the character set format would have succeeded.
// But we don't know what comes next, so we put the
// character back first.
// Although one character of pushback is guaranteed,
if (ungetc(ch,stdin) == EOF)
{
// pushback failed
exit(EXIT_FAILURE);
}
scanf("%27[^\n]%*c",buff);
printf("%s\n",buff);
}
}
使用fgets
,真的。它更好。