Unix C 文件,scanf 忽略空格
Posted
技术标签:
【中文标题】Unix C 文件,scanf 忽略空格【英文标题】:Unix C files , scanf is ignoring whitespace 【发布时间】:2021-12-19 00:33:45 【问题描述】:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
void main (int argc, char* arcv[])
int fd, quest_num, i, j;
char* str;
char temp[2], buffer[20];
fd = open(arcv[1], O_WRONLY | O_CREAT, 0664);
printf("Insert number of questions\n");
scanf("%s", str);
write(fd, str, sizeof(str));
write(fd, "\n", 1);
quest_num = atoi(str);
for (i = 1; i <= quest_num; i++)
printf("Insert question %d\n", i);
scanf("%[^\n]s", buffer);
printf("\n %s \n", buffer);
write(fd, "Question ", );
sprintf(temp, "%d", i);
write(fd, temp, sizeof(temp));
write(fd, "\n", 1);
write(fd, str, sizeof(temp));
write(fd, "\n", 1);
close(fd);
我想这样输入:
Insert Number of Question:
2
Insert Question 1:
X+1=0 x=?
Insert Question 2:
X+y=0
在文件内容中我希望它看起来像这样:
Question 1: X+1=0 x=?
1. 5
2. 2
3. 0
4. 1 Question 2: X+y=0
1. X=y
2. X= y
3. X=1
4. Y=1
但我在终端得到了这个:
Insert number of questions
2
Insert question 1
x+y x=?
Insert question 2 (input is ignored here)
在文件里面:
2
Question 1
x+
Question 2
x=
Question 3
2
总而言之,scanf
忽略了空格输入,文件内容中有一个额外的循环。
【问题讨论】:
为什么%[^\n]
后面有s
?那永远不会匹配任何东西。
@Barmar 我试过 %[^\n]s、%[^\n] 和 %s。它们都不起作用
您从未为str
分配任何内存,因此您会导致scanf("%s", str);
出现未定义的行为。
sizeof(str)
是指针的大小,而不是输入的字符数。使用strlen()
获取字符串的长度。
使用scanf("%s")
后,输入缓冲区留在换行符处。下一个 scanf("%[^\n]s", buffer);
将立即停止,因为没有非换行符。
【参考方案1】:
基本问题是,当您扫描与换行符(%s
或 %[^\n]
)不匹配的内容时,它不会读取行尾的换行符并将其留给下一个 stdio输入例程读取。您需要以某种方式实际读取并丢弃这些换行符。
最简单的方法是使用fgets
代替scanf
来读取输入行。
printf("Insert number of questions\n");
fgets(buffer, sizeof(buffer), stdin);
write(fd, buffer, strlen(buffer));
quest_num = atoi(buffer);
for (i = 1; i <= quest_num; i++)
printf("Insert question %d\n", i);
fgets(buffer, sizeof(buffer), stdin);
请注意,fgets
将读取行包括换行符,并且换行符将在缓冲区中,因此如果您不想要它,则需要将其显式删除.
如果您确实必须使用 scanf,您可以在格式中使用空格来显式跳过前导空格(包括任何延迟的换行符),这实际上可能是可取的。
printf("Insert number of questions\n");
scanf("%19s", buffer);
write(fd, str, strlen(buffer));
write(fd, "\n", 1);
quest_num = atoi(buffer);
for (i = 1; i <= quest_num; i++)
printf("Insert question %d\n", i);
scanf("% 19[^\n]", buffer);
printf("\n %s \n", buffer);
请注意,当使用带有 %s
或 %[
和固定大小缓冲区的 scanf 时,您应该在格式中使用明确的大小以避免缓冲区溢出
【讨论】:
以上是关于Unix C 文件,scanf 忽略空格的主要内容,如果未能解决你的问题,请参考以下文章