gpt4 book ai didi

c - scanf() 中的缓冲区溢出

转载 作者:行者123 更新时间:2023-11-30 15:06:16 30 4
gpt4 key购买 nike

我在网上寻找这个问题的解决方案,但没有结果。我正在尝试使用 scanf() 进行 while 循环来只读字符。如果用户输入超过 3 个字符,则会显示错误。

但是,如果我输入 3 个字符并按 Enter 键,我的代码将部分工作,而无需执行循环,这就是我想要的。如果我输入 4 个字符并按 Enter 也可以,它会执行循环并说“太长”,对于 5 个字符同样如此 + 输入我想要的内容。

但是,如果我输入 7 个字符并输入,它将执行循环并立即退出程序。有什么建议吗?

诗。对于任何语法错误,我深表歉意,但英语是我的第二语言。

#include<stdio.h>
int main(){
char alo;
char alo1;
char alo2;
char alo3;

printf("enter 3 characters: ");
scanf(" %c %c %c%c", &alo, &alo1, &alo2, &alo3);

while(alo3!='\r' && alo3!='\n'){
printf("too long \n");
printf("enter ");
scanf(" %c %c %c%c", &alo, &alo1, &alo2, &alo3);
}
return 0;
}

最佳答案

仅使用scanf()

仅使用 scanf() 来实现这一点需要一定的技巧。这不是最好的编码方式,但是......

#include <stdio.h>

int main(void)
{
char alo0;
char alo1;
char alo2;
char alo3;

printf("enter 3 characters: ");

while (scanf(" %c %c %c%c", &alo0, &alo1, &alo2, &alo3) == 4 &&
alo3 != '\r' && alo3 != '\n')
{
char buffer[4096];
if (scanf("%4095[^\n]", buffer) == EOF)
break;
printf("too long\n");
printf("enter 3 characters: ");
}

printf("Got [%c][%c][%c]\n", alo0, alo1, alo2);
return 0;
}

while() 条件使用 scanf() 读取四个字符,跳过前三个字符之前的空格。请注意,可以在字符之间添加换行符; scanf() 不在乎。如果您想要基于行的输入,scanf() 根本不适合这项工作!但是,假设读取了 4 个字符,并且第四个字符既不是回车符也不是换行符,则代码使用:

        char buffer[4096];
if (scanf("%4095[^\n]", buffer) == EOF)
break;

读取换行符之前但不包括换行符的任何字符。它不介意是否没有这样的字符,因此 scanf() 返回 0。然后代码会提示您输入正确的数据并转到主 scanf() >。这会跳过留下的换行符,然后再次查找三个字符。

while 循环退出时,可能是因为它得到了三个字符和一个换行符,或者因为它得到了更少的字符和 EOF,或者因为清理 scanf() 检测到 EOF。该代码不会尝试区分这些值(但应该这样做),只是打印出三个值。解决这个问题并不难。只需将每个 scanf() 的返回值分配给一个变量,然后在循环后进行测试:

int rc;
while ((rc = scanf(…)) == 4 && …)
{

if ((rc = scanf(…)) == EOF)
break;

}

if (rc == 4)
printf(…);
else
printf("Didn't get 3 characters as requested\n");

使用fgets()进行行输入

就个人而言,我认为使用 fgets()sscanf() 更容易/更好,如下所示:

#include <stdio.h>

int main(void)
{
char alo0;
char alo1;
char alo2;
char alo3;
char buffer[4096];
int rc = 0;

printf("enter 3 characters: ");

while (fgets(buffer, sizeof(buffer), stdin) != 0 &&
(rc = sscanf(buffer, " %c %c %c%c", &alo0, &alo1, &alo2, &alo3)) == 4 &&
alo3 != '\r' && alo3 != '\n')
{
printf("too long\n");
printf("enter 3 characters: ");
// In case you get 4 characters but the 4th was not a newline
// and then you get EOF
rc = 0;
}

if (rc == 4)
printf("Got [%c][%c][%c]\n", alo0, alo1, alo2);
else
printf("Didn't get 3 characters as requested\n");
return 0;
}

这可能会报告字符串太长或不正确。

关于c - scanf() 中的缓冲区溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39262390/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com