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

C语言中fgetc()函数失效问题:为何两段代码表现不同

问题分析与解决

你的第一段代码无法正常读取第一个字符的核心原因是:文件指针已经被移动到了文件末尾。

具体问题拆解

  1. 文件指针位置耗尽
    在第一段代码的do-while循环中,你通过fgetc(fp)不断读取文件内容,直到遇到EOF(文件结束符)。此时文件内部的位置指针已经指向了文件的最后一个字节之后,后续再调用fgetc(fp)只会返回EOF,自然无法读到文件开头的1。

  2. char类型存储fgetc返回值的隐患
    fgetc的返回值是int类型,它会返回读取到的字符(转换为unsigned char后再转为int),或者返回EOF(一个在int范围内的负值)。如果用char存储返回值,当系统中char是有符号类型时,某些字符(比如ASCII值为0x80-0xFF的字符)会被错误识别为EOF,导致循环提前终止或者判断错误。

  3. 缺少文件打开成功的检查
    如果fopen调用失败(比如文件不存在、权限不足),fp会是NULL,后续对fp的操作会导致程序崩溃,必须添加检查:

    fp = fopen("a.txt", "r");
    if (fp == NULL) {
        perror("Failed to open file");
        return 1;
    }
    

修复方案

要实现统计数字个数后再读取第一个字符,有两种常见方法:

  • 方法一:统计完成后重置文件指针
    在循环结束后,调用rewind(fp)将文件指针重置到文件开头,或者用fseek(fp, 0, SEEK_SET):

    FILE* fp;
      char digit_char;
      int NUM=1;
      fp = fopen("a.txt", "r");
      if (fp == NULL) {
          perror("Open file failed");
          return 1;
      }
      int ch; // 改为int类型
      do
      {
          ch = fgetc(fp);
          if (ch == ',')
          {
              NUM++;
          }
      } while (ch != EOF);
    
      rewind(fp); // 重置文件指针到开头
    
      int* arr;
      arr = malloc(sizeof(int) * NUM); // C中无需强制转换malloc返回值
      if (arr == NULL) {
          perror("Malloc failed");
          fclose(fp);
          return 1;
      }
    
      digit_char = fgetc(fp); // 现在可以读到第一个字符'1'
      
      free(arr);
      fclose(fp);
    
  • 方法二:一次遍历完成两个操作
    不需要两次遍历文件,第一次读取时同时记录第一个字符和统计逗号数量,效率更高:

    FILE* fp;
      char digit_char = 0;
      int NUM=1;
      fp = fopen("a.txt", "r");
      if (fp == NULL) {
          perror("Open file failed");
          return 1;
      }
      int ch;
      int first_read = 1;
      while ((ch = fgetc(fp)) != EOF) {
          if (first_read) {
              digit_char = ch;
              first_read = 0;
          }
          if (ch == ',') {
              NUM++;
          }
      }
    
      int* arr = malloc(sizeof(int) * NUM);
      if (arr == NULL) {
          perror("Malloc failed");
          fclose(fp);
          return 1;
      }
    
      // 后续处理数组...
      
      free(arr);
      fclose(fp);
    

为什么第二段代码正常?

第二段代码没有执行任何移动文件指针的循环,打开文件后直接调用fgetc(fp),此时文件指针默认指向文件开头,自然能读到第一个字符1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:45:33