我正在使用这段代码来验证结构中输入的长度,以便文件不会爆炸,但我不认为我正在执行它。
do
{
inputflag=0;
printf("Passenger ID no: ");
gets(newRes.idCard);
if((strlen(newRes.idCard))>7)
{
printf("invalid input \n");
inputflag=1;
}
fflush(stdin);
} while(inputflag==0);
答案 0 :(得分:3)
为了正确刷新标准输入,您应该执行以下操作:
int c;
while ((c = getchar()) != '\n' && c != EOF);
而不是gets
,您应该使用fgets,因为您可以将字符数限制为输入缓冲区的大小。
gets
将不知道长度,因此如果用户输入的内容超过缓冲区提供的数量,则可能导致缓冲区溢出。
答案 1 :(得分:3)
您的gets
电话不安全。它可以接受比您分配的更多字符。吊杆。
假设您为.idCard
分配了至少8个字节(即7个字符加终结符),请考虑使用:
fgets(newRes.idCard, 7+1, stdin);
这可以确保您不会接受太多的字符。它会在必要时截断。检查fgets
的返回值是否成功。
(man fgets
)
编译此示例代码并进行学习。我希望你能在这里找到你想要的东西。
#include <stdio.h>
#include <string.h>
#define MAX_ID_LEN (7)
int main() {
char idCard[MAX_ID_LEN+1];
printf("ID: ");
if (fgets(idCard, MAX_ID_LEN+1, stdin)) {
char *cLast = idCard + strlen(idCard)-1;
if (*cLast == '\n')
*cLast = 0; // strip newline *if* present
printf("Success! idCard='%s'\n", idCard);
} else {
printf("Failure.\n");
}
return 0;
}
请注意,有几行代码可以检查输入是否包含换行符并删除它。 fgets
确保换行,除非用户输入的ID超过7个字符。我希望这对你来说很清楚。
或者,这可能不会让您分心:(只需使用fscanf
)
#include <stdio.h>
int main() {
char idCard[7+1];
printf("ID: ");
fscanf(stdin, "%7s", idCard);
printf("idCard='%s'\n", idCard);
return 0;
}
答案 2 :(得分:1)
在将数据读入太小的缓冲区后检查长度为时已晚。首先将数据读入一个大的保持缓冲区。
fgets()
是过时gets()
的绝佳替代品。请记住剥离潜在的结尾\n
。
还要避免像'7'这样的幻数。使用类似sizeof(newRes.idCard)
的内容。
在设计良好的代码中fflush(stdin)
不需要,应该避免,因为它不可移植。
int inputflag = 0; // Not clear is OP needs this value after the while loop.
do {
printf("Passenger ID no: ");
char buf[sizeof(newRes.idCard) * 2]; ' twice as big as needed.
if (fgets(buf, sizeof buf, stdin) == NULL) {
inputflag = 1;
break;
}
size_t Len = strlen(buf);
if (Len && buf[Len-1] == '\n') buf[--Len] = '\0';
if(Len >= sizeof(newRes.idCard)) {
printf("invalid input \n");
inputflag = 1;
}
else {
strcpy(newRes.idCard, buf);
}
} while (inputflag == 0);