从C中的标准输入识别空行
我很难识别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
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()
、usedfgets()
或*nixgetline()
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()
或*nixgetline()
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。提供的代码不是答案,而是提纲。谢谢,我刚刚通过反复试验发现了这一点,并自己找到了答案。我