如何在c程序中扫描行而不是从文件中扫描

时间:2017-07-12 10:40:36

标签: c

如何使用c程序扫描用户输入的总行数?

我尝试了scanf("%99[^\n]",st),但是当我在此扫描声明之前扫描某些内容时,它无法正常工作。如果这是第一个扫描声明,则无效。

4 个答案:

答案 0 :(得分:1)

  

如何使用c程序扫描用户输入的总行数?

读取一行输入的方法有很多,而您对 scan 这个词的使用表明您已经专注于scanf()工作的功能。这很不幸,因为虽然你可以(在某种程度上)用scanf()达到你想要的效果,但它绝对不是读取一条线的最佳工具。

正如评论中所述,您的scanf()格式字符串将停止在换行符处,因此下一个scanf()将首先找到该换行符,并且它可以' t匹配[^\n](表示除了换行符之外的任何内容)。由于换行符只是另一个空格字符,因此在转化前添加空格会默默地将其用掉;)

但现在为了更好的解决方案:假设您只想使用标准C函数,那么已经有一个函数完全读取一行:fgets()。以下代码段应解释其用法:

char line[1024];
char *str = fgets(line, 1024, stdin); // read from the standard input

if (!str)
{
    // couldn't read input for some reason, handle error here
    exit(1); // <- for example
}

// fgets includes the newline character that ends the line, but if the line
// is longer than 1022 characters, it will stop early here (it will never 
// write more bytes than the second parameter you pass). Often you don't 
// want that newline character, and the following line overwrites it with
// 0 (which is "end of string") **only** if it was there:
line[strcspn(line, "\n")] = 0;

请注意,您可能想要使用strchr()来检查换行符,因此您实际上知道您是否拥有整行或者您的输入缓冲区是否很小。在后一种情况下,您可能希望再次致电fgets()

答案 1 :(得分:0)

scanf()永远不应该用于用户输入。从用户获取输入的最佳方式是使用fgets()。

了解详情:http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html

答案 2 :(得分:0)

  

如何使用c程序扫描用户输入的总行数?

scanf("%99[^\n]",st)几乎读取​​

使用C标准库,

  

文本流是由组成的有序字符序列,每行包含零个或多个字符以及终止的换行符。最后一行是否需要终止换行符是实现定义的。 C11dr§7.21.22

scanf("%99[^\n]",st)无法阅读该行的结尾'\n'

这就是为什么在第二次通话时,'\n'仍然在stdin内阅读而scanf("%99[^\n]",st)将无法阅读。

方式使用scanf("%99[^\n]",st);或其变体作为阅读用户输入的一个步骤,但它们会受到影响1)不处理空白行"\n"正确2)缺少罕见的输入错误3)长线问题和其他细微差别。

首选便携式解决方案是使用fgets()。循环示例:

#define LINE_MAX_LENGTH 200
char buf[LINE_MAX_LENGTH + 1 + 1];  // +1 for long lines detection, +1 for \0
while (fgets(buf, sizeof buf, stdin)) {
  size_t eol = strcspn(buf, "\n");  **
  buf[eol] = '\0';  // trim potential \n
  if (eol >= LINE_MAX_LENGTH) {
    // IMO, user input exceeding a sane generous threshold is a potential hack
    fprintf(stderr, "Line too long\n");
    // TBD : Handle excessive long line
  }

  // Use `buf[[]`
}

许多平台支持getline()读取一行。

缺点:非C标准,允许黑客用疯狂的长线压倒系统资源。

在C中,没有伟大的解决方案。什么是最好的取决于各种编码目标。

**我更喜欢size_t eol = strcspn(buf, "\n\r");来读取可能以"\r\n"结尾的* nix环境中的行。

答案 3 :(得分:-1)

char str[1024];
char *alline = fgets(str, 1024, stdin);
scanf("%[^'\n']s",alline);

我认为正确的解决方案应该是这样的。它为我工作。 希望对您有所帮助。