首先,我想提一下我是编程新手。
我试图编写一个包含多个输入的程序,其中最后一个是字符串,当我使用gets()或fgets()函数时,它们从先前输入完成后读取输入。例如:
INSERT INTO categories(
category_id, name, created_time, description)
VALUES (?, ?, ?, ?);
样本输入/输出:
printf("Enter decimal:\n");
scanf("%d",&x);
printf("Enter string:\n");
gets(str[100]);
printf("%d\n%s",x,str);
但是,如果输入如下:
Enter decimal:
3\n //If I change line after inputting the decimal the program continues as if it already read the string
Enter string:
3
我想这就是gets()和fgets()函数的工作方式,但是有没有一种方法可以控制它,或者有替代方法(输入的字符串可能会很长 )
谢谢。
答案 0 :(得分:2)
详细了解C standard IO。请注意,gets
已过时且危险,但现已从C标准中删除。您永远不要使用它(请忘记它已经存在)。假设fgets(str, sizeof(str), stdin)
是gets
的 array ,例如,假设您是str
,而不是呼叫消失的char
。声明为char str[100];
。
您可能会用fgets
(甚至是getline(3),请参阅this)读整行,然后可能使用sscanf(或strtol或strtok,或使用您自己的lexing和parsing技术)。
请注意,sscanf
(如fscanf
和scanf
)返回已扫描的项目计数(并接受%n
),但并不关心行尾。您需要使用它。
请仔细阅读正在使用的功能的文档。
在读取真实文件时,您还可以使用fseek(带有ftell)在文件中重新定位。这在控制台上将不起作用(因为终端通常不是seekable终端。)
也许您可以使用一些terminal相关的库(例如ncurses或readline)。这些不在C11标准n1570中,并且可能在您的操作系统上不可用(但是在Linux和某些其他OS上,您已经拥有它们)。
请记住,您的stdin并不总是终端。考虑一下redirections和pipelines。
另请参阅How to Debug Small Programs。确保使用所有警告和调试信息来编译代码(如果使用GCC,则为gcc -Wall -Wextra -g
)。
如果您使用的是Linux或某些POSIX操作系统,请注意 stdin 与file descriptor 0(名为STDIN_FILENO
)有关。因此,如果您要等到输入可用,请考虑在该文件描述符上使用poll(2)。
PS。您的问题确实不清楚。我只是猜出你想做什么...。阅读更多文档后,请考虑对其进行改进...
答案 1 :(得分:1)
您的代码中存在多个问题:
gets()
已过时且存在风险,因为未将目标数组大小传递给该函数,因此如果用户输入过长,它就不能防止缓冲区溢出。最终,它已从最新版本的C标准中删除。请改用fgets()
。scanf()
和fgets()
容易出错,因为scanf()
会使部分用户输入处于待处理状态,例如用户在数字后键入换行符,并且该待处理的输入将被读取fgets()
来完成,在这种情况下,由于待定的换行符正是fgets()
期望结束其输入的内容,因此将立即返回。我建议使用fgets()
逐行读取输入,并使用sscanf
将输入转换为期望的类型。它具有允许轻松恢复错误的额外优势。
这是修改后的版本:
#include <stdio.h>
#include <string.h>
int main() {
char buf[100];
int x;
for (;;) {
printf("Enter decimal: ");
if (!fgets(buf, sizeof buf, stdin))
return 1;
if (sscanf(buf, "%d", &x) == 1)
break;
printf("Invalid input: not a number\n");
}
for (;;) {
printf("Enter string:\n");
if (!fgets(buf, sizeof buf, stdin))
return 1;
buf[strcspn(buf, "\n")] = '\0'; // strip the trailing newline if any
if (buf[0] != '\0')
break;
printf("Invalid input: empty string\n");
}
printf("%d\n%s\n", x, buf);
return 0;
}