繁体   English   中英

scanf()中的缓冲区溢出

[英]Buffer overflow in scanf()

我在网上寻找解决此问题的方法,但没有结果。 我正在尝试使用whilef循环使用scanf()仅读取字符。 如果用户键入的字符超过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;
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM