如何在C中进行行输入? [英] How to take a line input in C?

查看:67
本文介绍了如何在C中进行行输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在C语言中输入一行.

I was trying to take a full line input in C. Initially I did,

char line[100] // assume no line is longer than 100 letters.
scanf("%s", line);

忽略安全漏洞和缓冲区溢出,我知道这绝不会超过输入一个单词.我又修改了

Ignoring security flaws and buffer overflows, I knew this could never take more than a word input. I modified it again,

scanf("[^\n]", line);

这当然不能超过一行输入.但是,以下代码遇到了无限循环,

This, of course, couldn't take more than a line of input. The following code, however was running into infinite loop,

while(fscanf(stdin, "%[^\n]", line) != EOF)
{
    printf("%s\n", line);
} 

这是因为 \ n 从未被使用过,并且会反复在同一点停止并在 line 中具有相同的值.所以我将代码改写为

This was because, the \n was never consumed, and would repeatedly stop at the same point and had the same value in line. So I rewrote the code as,

while(fscanf(stdin, "%[^\n]\n", line) != EOF)
{
    printf("%s\n", line);
}

此代码 起作用 完美(或我认为),可以从文件中输入.但是,对于来自 stdin 的输入,这会产生神秘,怪异,不清晰的行为.仅在输入第二行之后,才会打印第一行.我无法理解实际发生的情况.

This code worked impeccably(or so I thought), for input from a file. But for input from stdin, this produced cryptic, weird, inarticulate behavior. Only after second line was input, the first line would print. I'm unable to understand what is really happening.

我正在做的就是这个.记下字符串,直到遇到 \ n ,将其存储在 line 中,然后从输入缓冲区中使用 \ n .现在打印此,并准备好输入的下一行.还是我被误导了?

All I am doing is this. Note down the string until you encounter a \n, store it in line and then consume the \n from the input buffer. Now print this line and get ready for next line from the input. Or am I being misled?

但是,在发布此问题时,我找到了一个更好的替代方法

At the time of posting this question however, I found a better alternative,

while(fscanf(stdin, "%[^\n]%*c", line) != EOF)
{
    printf("%s\n", line);
}

这在所有情况下都可以正常工作.但是我的问题仍然存在.这段代码怎么来了

This works flawlessly for all cases. But my question still remains. How come this code,

while(fscanf(stdin, "%[^\n]\n", line) != EOF)
{
    printf("%s\n", line);
}

可以处理文件中的输入,但是会导致标准输入中的输入出现问题?

worked for inputs from file, but is causing issues for input from standard input?

推荐答案

使用 fgets(). @FredK

char buf[N];
while (fgets(buf, sizeof buf, stdin)) {
  // crop potential \n if desired.
  buf[strcspn(buf, "\n")] = '\0'; 
  ...
}

尝试使用 scanf()进行用户输入有很多问题,这使其容易受到误用或代码攻击.

There are to many issues trying to use scanf() for user input that render it prone to mis-use or code attacks.

// Leaves trailing \n in stdin
scanf("%[^\n]", line)

// Does nothing if line begins with \n. \n remains in stdin
// As return value not checked, use of line may be UB.
// If some text read, consumes \n and then all following whitespace: ' ' \n \t etc.
//    Then does not return until a non-white-space is entered.
//    As stdin is usually buffered, this implies 2 lines of user input.
// Fails to limit input.
scanf("%[^\n]\n", line)

// Does nothing if line begins with \n. \n remains in stdin
// Consumes 1 char after `line`, even if next character is not a \n
scanf("%99[^\n]%*c", line)

检查EOF通常是错误检查. @Weather Vane 以下是\ n为输入的 first ,由于未填充 line ,因此返回0.由于 0!= EOF ,代码继续使用未初始化的 line 导致UB.

Check against EOF is usual the wrong check. @Weather Vane The following, when \n is first entered, returns 0 as line is not populated. As 0 != EOF, code goes on to use an uninitialized line leading to UB.

while(fscanf(stdin, "%[^\n]%*c", line) != EOF)

请考虑在下面输入"1234 \ n".可能是无限循环,因为第一个 fscanf()读为"123",扔掉"4",下一个 fscanf()调用卡在\ n上.

Consider entering "1234\n" to the following. Likely infinite loop as first fscanf() read "123", tosses the "4" and the next fscanf() call gets stuck on \n.

while(fscanf(stdin, "%3[^\n]%*c", line) != EOF)

检查 * scanf()的结果时,检查所需的内容,而不是检查不需要的值之一.(但即使以下情况也有其他麻烦)

When checking the results of *scanf(), check against what you want, not against one of the values you do not want. (But even the following has other troubles)

while(fscanf(stdin, "%[^\n]%*c", line) == 1)


关于最近的 scanf()以读取:

char buf[100];
buf[0] = 0;
int cnt = scanf("%99[^\n]", buf);
if (cnt == EOF) Handle_EndOfFile();
// Consume \n if next stdin char is a \n
scanf("%*1[\n]");
// Use buf;


while(fscanf(stdin,%[^ \ n]%* c",line)!= EOF)
可以处理文件中的输入,但是会导致标准输入中的输入出现问题?

while(fscanf(stdin, "%[^\n]%*c", line) != EOF)
worked for inputs from file, but is causing issues for input from standard input?

张贴示例代码和输入/数据文件将很有用.在发布少量代码的情况下,有一些潜在的原因.

Posting sample code and input/data file would be useful. With modest amount of code posted, some potential reasons.

超限是UB
输入以 \ n 开头,导致UB
文件或 stdin 均未以相同模式打开. \ r 不能一次翻译.

line overrun is UB
Input begins with \n leading to UB
File or stdin not both opened in same mode. \r not translated in one.

注意:当一行为100个字符时,以下操作失败.因此,满足假设条件cal仍会导致UB.

Note: The following fails when a line is 100 characters. So meeting the assumption cal still lead to UB.

char line[100] // assume no line is longer than 100 letters.
scanf("%s", line);

这篇关于如何在C中进行行输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆