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

能否用fgets或gets_s正确读取空字符?读取含空字符输入需用fgetc/fread吗?

读取含空字符的输入:fgets/gets_s的局限与正确方案

直接给你明确结论:fgets和gets_s都没法正确读取包含空字符的输入,如果你的需求是从stdin读取带空字符的内容,必须用fgetc或者fread这类面向原始字节的函数。

为什么fgets/gets_s不行?

这俩函数的设计目标是处理C语言里标准的“以空字符'\0'结尾的字符串”。对它们来说,空字符不是普通的输入数据,而是字符串的终止标志——一旦读取到'\0',函数就会停止读取,并且把这个'\0'作为字符串的结束符存在缓冲区里,后面的输入内容直接被忽略。哪怕你的输入里有多个字节,只要中间出现了'\0',它们就会认为读取完成了,根本没法完整捕获包含空字符的输入。

而且gets_s虽然是gets的“安全版本”(限制了读取长度),但核心逻辑还是围绕C风格字符串,同样把'\0'当终止符,所以完全不适用这种场景。

正确的做法:用fgetc或fread

这两个函数是直接操作原始字节的,不会把任何字节当成特殊的终止符(除了fgetc会识别EOF),能完整读取所有输入字节,包括空字符。

举两个简单的示例:

用fread批量读取

#include <stdio.h>

int main() {
    char buffer[256];
    // 读取最多256字节的输入,不管有没有空字符
    size_t bytes_read = fread(buffer, 1, sizeof(buffer), stdin);
    
    printf("总共读取了 %zu 字节的数据\n", bytes_read);
    // 遍历输出每个字节的十六进制值,能看到空字符(0x00)
    for (size_t i = 0; i < bytes_read; i++) {
        printf("第 %zu 字节: 0x%02X\n", i, (unsigned char)buffer[i]);
    }
    return 0;
}

用fgetc逐个读取

#include <stdio.h>

int main() {
    char buffer[256];
    size_t read_count = 0;
    int current_char;

    // 逐个读取直到EOF或者缓冲区满
    while (read_count < sizeof(buffer) && (current_char = fgetc(stdin)) != EOF) {
        buffer[read_count++] = (char)current_char;
    }

    printf("总共读取了 %zu 字节的数据\n", read_count);
    return 0;
}

这两种方式都能正确捕获包含空字符的输入,完全不受'\0'的影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:48:13