scanf()中的缓冲区溢出

时间:2016-09-01 03:46:41

标签: c

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

但是,如果我键入3个字符并且按回车键,我的代码部分工作,而不执行循环,这就是我想要的。如果我输入4个字符然后按回车键也可以执行循环并且说“太长”同样适用于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;
}

1 个答案:

答案 0 :(得分:1)

仅使用scanf()

仅使用scanf()来实现这一目标需要一定数量的jiggery-pokery。这不是编码它的最好方法,但是......

#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;
}

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