如何从scanf函数获取换行符即使它是唯一的输入 [英] How to get newline character from scanf even if it's the only input
问题描述
我在做家庭作业,要求我读一个整数 N
重新presenting循环的大小,然后读取一行字符<$ C $ ç> N 时间和用户的输入之后打印出来。所以我用 scanf函数
,然后我跟打印的printf
。问题是,如果用户输入只是一个换行符,它应该打印另一 \\ n
,但 scanf函数
似乎忽略输入时,它的一个 \\ n
。
有没有什么办法让这个作业和 scanf函数
或者我应该试试别的?
INT I;
scanf函数(%d个,&安培; I)
对于(INT克拉= 0; CT&LT;我; CT ++)
{
字符的buff [28];
scanf函数(%S,浅黄色); //如果我只是preSS进入这里
PRTINF(%S \\ n,浅黄色); //那么我必须\\ n \\ n这里
}
使用与fgets
在一条线上阅读更简单,更强大的:
如果(!与fgets(BUFF,28,标准输入))
{
//读取失败,执行相应的错误处理
//我们只是在这里退出
出口(EXIT_FAILURE);
}
//我们已成功读取在一条线上,或至少第一27
//行字符。检查全行是否被读取,
//如果是,线路是否是空的
为size_t L = strlen的(BUFF); //&LT;&string.h中GT;必须包含
如果(BUFF [L-1] =='\\ n')
{
//全线被读取,删除尾随换行符,除非
//行是空的
如果(L→1)
{
抛光轮[1- 1] = 0;
}
}
其他
{
//输入太长,现在该怎么办?
//离开其余的输入为下一次迭代或
//清空输入缓冲器?
}
的printf(%S \\ n,浅黄色);
这不符合工作scanf函数(%S,BUFF)
,因为大多数 scanf函数
转换忽略前导空格:
输入空白字符(由
isspace为
函数指定)被跳过,除非
该规范包括[
,C
或N
说明
块引用>因此,如果用户输入一个空行,
scanf函数
忽略输入,除非它的格式是例外之一。您可以使用
scanf函数
用字符集格式而不是,scanf函数(%27 [^ \\ n]的%* C,浅黄色);
读取所有的字符,直到一个换行符(但不限于
28 - 1
在这里,以避免缓冲区溢出),然后消耗换行而不保存它(*
在%* C
转换说明燮presses分配),将手柄完全由空白的非空行,其中%S
转换不会。但是,如果输入的第一个字符是换行,那么27%[^ \\ n]
转换失败(感谢的 chux 提请注意这一点),换行留在输入缓冲区,如果换行不从输入缓冲区取出随后与该格式扫描也不能通过。一个稍微强大的(但丑;不处理太长输入)使用循环
scanf函数
会,就我所看到的,前需要检查一个换行符扫描,如:的for(int克拉= 0; CT&LT;我++ CT)
{
INT CH =的getchar();
如果(CH == EOF)
{
//坏事发生;我们退出
出口(EXIT_FAILURE);
}
如果(CH =='\\ n')
{
//我们有一个空行
的printf(\\ n \\ n);
}
其他
{
//第一个字符不是一个换行符,扫描
//使用的字符集的格式将成功。
//但是我们不知道接下来会发生什么,所以我们把
//字符回到第一位。
//虽然推回一个字符的保证,
如果(与ungetc(CH,标准输入)== EOF)
{
//失败后推
出口(EXIT_FAILURE);
}
scanf函数(%27 [^ \\ n]的%* C,浅黄色);
的printf(%S \\ n,浅黄色);
}
}使用
与fgets
,真的。这是更好的。I'm doing homework that asks me to read an integer
n
representing the size of a loop and then read a line of charactersn
times and print it right after the user's input. So I usedscanf
and then I print it withprintf
. The problem is that if the user's input is only a newline character, it should print another\n
, butscanf
seems to ignore the input when it's a single\n
.Is there any way to make this assignment with
scanf
or should I try something else?int i; scanf("%d", &i); for(int ct=0; ct<i; ct++) { char buff[28]; scanf("%s", buff); // if I just press enter here prtinf("%s\n", buff); // then I must get \n\n here }
解决方案Using
fgets
to read in a line is simpler and more robust: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);
It doesn't work with
scanf("%s",buff)
because mostscanf
conversions ignore leading white space:Input white-space characters (as specified by the
isspace
function) are skipped, unless the specification includes a[
,c
, orn
specifier.So if the user inputs an empty line,
scanf
ignores that input unless its format is one of the exceptional.You can use
scanf
with a character set format instead,scanf("%27[^\n]%*c", buff);
to read all characters until a newline (but limited to
28 - 1
here to avoid buffer overruns), and then consume a newline without storing it (the*
in the%*c
conversion specifier suppresses assignment), that would handle non-empty lines consisting entirely of whitespace, which the%s
conversion would not. But if the first character of the input is a newline, the%27[^\n]
conversion fails (thanks to chux for drawing attention to that), the newline is left in the input buffer, and subsequent scans with that format would also fail if the newline isn't removed from the input buffer.A somewhat robust (but ugly; and not dealing with too long input) loop using
scanf
would, as far as I can see, need to check for a newline before scanning, e.g.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); } }
Use
fgets
, really. It's better.这篇关于如何从scanf函数获取换行符即使它是唯一的输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!