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

使用fgets和sscanf读取文件内容时copies变量无法正确取值问题

读取失败的核心原因

导致copies变量无法正确读取的问题集中在以下几点:

  • sscanf格式字符串语法错误:你写的%f[^,],%d[^ ]不符合scanf的格式规则,%f已经完成浮点数读取,后续的[^,]会被识别为独立的格式匹配符,但你没有提供对应的字符数组接收匹配结果,格式匹配从这里直接错位,后续的%d完全无法匹配到正确的整数,copies一直保留初始化的0值。
  • 变量名不匹配:代码中定义的输出变量是author、title、genre、price、copies,但你传入sscanf的是autore、titolo、genere、prezzo、copie,两组变量完全无关,哪怕格式匹配正确,输出的还是初始化的旧值。
  • 其他隐藏问题:while(!feof(fp))的写法会导致文件读完后多执行一次无效读取;未判断fopen返回值,文件不存在时会直接崩溃;字段前后的空格和title的引号没有处理,会被读取到字段内容中。

更优的实现方式

修正后的代码如下:

#include <stdio.h>

int main() {
    FILE *fp = NULL;
    char string[100];
    char title[30], author[30], genre[30];
    float price;
    int copies = 0;

    // 打开文件并判断是否成功
    fp = fopen("file.txt", "r");
    if (fp == NULL) {
        perror("fopen failed");
        return 1;
    }

    // 直接用fgets返回值判断是否读完,避免feof的问题
    while(fgets(string, sizeof(string), fp) != NULL) {
        // 格式串适配带引号的title,限制读取长度避免缓冲区溢出
        if (sscanf(string, "%29[^,], \"%29[^\"]\", %29[^,], %f, %d",
                   author, title, genre, &price, &copies) == 5) {
            // 匹配成功才输出,避免无效行的干扰
            printf("%s %s %s %.2f %d\n", author, title, genre, price, copies);
        }
    }

    fclose(fp);
    return 0;
}

关键修改点说明:

  • 格式串适配字段规则:专门处理了title的双引号,同时每个字符串读取限制29字符,预留\0的位置避免缓冲区溢出
  • 增加匹配成功判断:sscanf返回成功匹配的字段数,只有返回5时才代表所有字段都读取成功,避免无效行干扰
  • 替换feof逻辑:直接用fgets的返回值判断文件是否读完,逻辑更严谨
  • 增加文件打开失败判断,避免空指针访问

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 15:27:00