从C中的标准输入识别空行

从C中的标准输入识别空行,c,parsing,input,C,Parsing,Input,我很难识别C中标准输入的空行。我有以下代码: char *line = NULL; int done = 0; while (!done) { scanf("%m[^\n]", &line); if (line != NULL) //do something with line else done = 1; scanf("\n"); free(line); 这些行应该是用户的命令。假设他只允许打电话 insert something delet

我很难识别C中标准输入的空行。我有以下代码:

char *line = NULL;
int done = 0;
while (!done) {
   scanf("%m[^\n]", &line);
   if (line != NULL)
      //do something with line
   else
      done = 1;
scanf("\n");
free(line);
这些行应该是用户的命令。假设他只允许打电话

insert something
delete something


在任何其他情况下,程序都应该输出,比如说,“命令不允许”。我可以在任何情况下这样做,除了一个——当输入上有一个空行时——我不知道如何识别一个。如果您能提供帮助,我将不胜感激。

此答案中的所有信息均摘自
man scanf

%[
格式代码与空字符串不匹配:

[
匹配指定的接受字符集的非空字符序列

请记住,
scanf
有一个非常有用的返回值:

这些函数返回成功匹配和分配的输入项的数量,该数量可以少于提供的数量,如果早期匹配失败,甚至可以为零

您应该始终检查scanf的返回值,因为如果无法成功匹配相应的输入项,则输出参数具有未指定的值

在这种情况下,返回值将告诉您换行符前面是否有非空字符串


如前所述,您的代码存在内存泄漏(假设读取了多行),因为
m
修饰符导致分配内存,而从不查看原始存储在相应参数中的值。因此,如果该参数包含以前分配的存储地址,它将被新分配的存储地址覆盖,并且以前的分配将泄漏

循环应为:

while (!done) {
  line = NULL; /* Not strictly necessary */
  if (scanf("%m[^\n]", &line) == 1) {
    /* Do something with line */
    free(line);
  } else {
    /* Handle an empty line */
  }
  /* skip trailing newline. See below. */
  getchar();
}
scanf(“\n”)
不仅跳过单个换行符。它与
scanf(“”
)没有什么不同;scanf格式中的任何空白:

匹配输入中任意数量的空白,包括无空白


如果您只想跳过单个换行符,请使用
getchar()

此答案中的所有信息都是从
man scanf
中提取的

%[
格式代码与空字符串不匹配:

[
匹配指定的接受字符集的非空字符序列

请记住,
scanf
有一个非常有用的返回值:

这些函数返回成功匹配和分配的输入项的数量,该数量可以少于提供的数量,如果早期匹配失败,甚至可以为零

您应该始终检查scanf的返回值,因为如果无法成功匹配相应的输入项,则输出参数具有未指定的值

在这种情况下,返回值将告诉您换行符前面是否有非空字符串


如前所述,您的代码存在内存泄漏(假设读取了多行),因为
m
修饰符导致分配内存,而从不查看原始存储在相应参数中的值。因此,如果该参数包含以前分配的存储地址,它将被新分配的存储地址覆盖,并且以前的分配将泄漏

循环应为:

while (!done) {
  line = NULL; /* Not strictly necessary */
  if (scanf("%m[^\n]", &line) == 1) {
    /* Do something with line */
    free(line);
  } else {
    /* Handle an empty line */
  }
  /* skip trailing newline. See below. */
  getchar();
}
scanf(“\n”)
不仅跳过单个换行符。它与
scanf(“”
)没有什么不同;scanf格式中的任何空白:

匹配输入中任意数量的空白,包括无空白


如果只想跳过单个换行符,请使用
getchar()

而不是使用
scanf()
、used
fgets()
或*nix
getline()

scanf()
设计用于读取格式化数据-它对行的处理效果稍好。
fgets()
用于读取一行(0个或多个字符,最多包含一个最终的
'\n'
),并通过向目标缓冲区追加一个空字符
'\0'
将其转换为C字符串

char line[100];
while (!done) {
  // scanf("%m[^\n]", &line);
  if (fgets(line, sizeof line, stdin) == NULL) {
    // EOF or input error occurred, for now let us just clear line
    line[0] = 0; 
  }
  // get rid of potential trailing \n
  line[strcspn(line, "\n")] = 0;
  if (line[0]) 
    //do something with line
  else
    done = 1;
} 

使用的不是
scanf()
,而是
fgets()
或*nix
getline()

scanf()
设计用于读取格式化数据-它对行的处理效果稍好。
fgets()
用于读取一行(0个或多个字符,最多包含一个最终的
'\n'
),并通过向目标缓冲区追加一个空字符
'\0'
将其转换为C字符串

char line[100];
while (!done) {
  // scanf("%m[^\n]", &line);
  if (fgets(line, sizeof line, stdin) == NULL) {
    // EOF or input error occurred, for now let us just clear line
    line[0] = 0; 
  }
  // get rid of potential trailing \n
  line[strcspn(line, "\n")] = 0;
  if (line[0]) 
    //do something with line
  else
    done = 1;
} 

如果你想阅读整行文字,那么你最好改用。如果你确实使用
fgets
,那么空行只会包含一个换行符,仅此而已。如果你想阅读整行文字,那么你最好改用。如果你确实使用
fgets
,那么空行只会包含一个换行符仅此而已。尽管我非常希望,您的解决方案似乎不起作用。它仍然跳过所有空行。我相信scanf函数不太关心空行lines@jytug:如我所说,scanf(“”)将跳过空行。我在示例代码中用getchar替换了它。@jytug:您可能需要检查getchar是否返回EOF。提供的代码不是答案,而是提纲。谢谢,我刚刚通过反复试验发现了这一点,并自己找到了答案。我非常感谢您的耐心,尽管我希望如此,但您的解决方案并不是这样似乎有效。它仍然跳过所有空行。我相信scanf函数不太关心空行lines@jytug:如我所说,scanf(“”)将跳过空行。我在示例代码中用getchar替换了它。@jytug:您可能想检查getchar是否返回EOF。提供的代码不是答案,而是提纲。谢谢,我刚刚通过反复试验发现了这一点,并自己找到了答案。我