You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

gets()与scanf()函数的区别及gets()读取输入输出乱码问题排查

问题分析:素数判断代码替换gets后输出乱码的原因及gets与scanf的区别
#include <stdio.h>
#include <math.h>

int testprime (int x )
{
    int i, root ;
    if (x == 2) {
        return 1 ;
    }
    if (x%2 == 0) {
        return 0 ;
    }
    root = sqrt (x) ;
    for (i = 3 ; i < root ; i ++) {
        if (x%i == 0 ) {
            return 0 ;
        }
    }
    return 1 ;
}

int main ( )
{
    int n ,  root ;
    printf ("Enter the testing number\n") ;
    //gets (n) ;
    scanf ("%d", &n) ;
    if (n <= 0) {
        printf ("Error \n") ;
    }
    if (n == 1)
        printf ("Unity number is %d\n",n) ;
    if (0 == testprime(n) )
        printf ("isn't a prime number\n") ;
    else {
        printf ("%d is a prime number \n",n) ;
    }
    return 0 ;
}

替换为gets(n)后输出乱码的成因

  1. 参数类型严重不匹配:gets()的入参要求是char*类型的字符缓冲区指针,作用是把用户输入的整行内容以ASCII字符串形式存储。代码中直接传入int类型变量n,gets()会把n的随机初始值当成内存地址直接写入数据,属于非法内存访问,轻则变量取值异常输出乱码,重则程序直接崩溃。
  2. 无类型转换逻辑:就算把参数修正为&n(传入int变量的地址),gets()也只会把输入的数字当成字符逐字节写入内存,比如输入123,实际写入的是'1'(ASCII 49)、'2'(ASCII 50)、'3'(ASCII 51)和字符串结束符\0,和整数123的二进制存储值完全不同,后续素数判断逻辑读取到的n值完全不符合预期,自然输出异常。
    额外说明:gets()本身是C11标准已经正式废除的不安全函数,完全不检查缓冲区长度,极易触发缓冲区溢出漏洞,任何场景下都不建议使用。

gets()与scanf()的核心区别

  • 功能定位不同:gets()是纯字符串读取函数,只能将输入内容以字符串形式存储,不支持任何格式转换;scanf()是格式化输入函数,支持%d、%f、%s等多种格式符,会自动将输入的字符串转换为对应类型的数值存储。
  • 输入终止逻辑不同:gets()只有遇到换行符才会终止读取,会读取换行前的所有内容(包括空格),并自动丢弃换行符,在字符串末尾补\0;scanf()默认以空白符(空格、换行、制表符)作为分隔符,读取到空白符就终止当前格式的读取。
  • 参数要求不同:gets()仅要求传入字符缓冲区的首地址;scanf()需要根据格式符传入对应类型变量的地址,比如用%d读取整数时必须传入int变量的指针&n,内部会将转换后的整数值写入对应内存地址。
  • 安全性不同:gets()完全不检查输入长度,只要输入内容长度超过缓冲区大小就会触发溢出,属于严重安全漏洞,已被标准废除;scanf()读取固定长度类型(如%d、%f)时风险可控,读取字符串时也可以通过%10s这类写法限制最大读取长度,避免溢出。
  • 缓冲区残留处理不同:gets()会读取并丢弃输入末尾的换行符,不会残留在输入缓冲区;scanf()用%d等非字符格式读取时,会跳过开头的空白符,但读取完成后剩余的换行符会留在输入缓冲区,可能影响后续getchar()、%c等对单个字符的读取操作。

内容的提问来源于stack exchange,提问作者Ashikul Islam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:45:03