C语言求助:统计文本文件首行数字数量遇技术难题
统计文本文件第一行的数字数量(C语言实现)
你之前使用fscanf(fd, "%d\n", &temp)得到第一个数字而非最后一个,问题出在fscanf的格式解析规则:
%d会自动跳过所有前导空白字符(空格、制表符等),读取第一个整数;- 格式串中的
\n会匹配任意数量的空白字符(包括后续的空格、换行),而不是仅匹配一个换行符。这导致执行完这条语句后,文件指针已经跳过了第一行的所有内容,所以temp只能拿到第一个整数-54。
下面提供两种可行的解决方案:
方法一:先读取整行再处理字符串
这种方法先把第一行完整读入内存,再遍历字符串统计数字个数,逻辑更直观,适合处理行长度有限的文本:
#include <stdio.h> #include <string.h> #include <ctype.h> int main() { FILE *fd = fopen("test.txt", "r"); if (!fd) { perror("Failed to open file"); return 1; } char line[1024]; // 可根据实际需求调整数组大小 if (fgets(line, sizeof(line), fd) == NULL) { perror("Failed to read first line"); fclose(fd); return 1; } int count = 0; char *ptr = line; while (*ptr != '\0') { // 跳过所有空白字符(除了换行) while (isspace((unsigned char)*ptr) && *ptr != '\n') { ptr++; } if (*ptr == '\n' || *ptr == '\0') { break; // 到达行尾或字符串结束 } // 判断是否是有效整数的起始:数字,或负号后跟数字 if (isdigit((unsigned char)*ptr) || (*ptr == '-' && isdigit((unsigned char)*(ptr + 1)))) { count++; // 跳过当前整数的所有字符 while (isdigit((unsigned char)*ptr) || *ptr == '-') { ptr++; } } else { // 非数字字符,直接跳过 ptr++; } } printf("第一行数字数量:%d\n", count); fclose(fd); return 0; }
逻辑说明:
- 用
fgets读取第一行到缓冲区; - 遍历字符串时,先跳过所有空白字符;
- 遇到有效整数的起始(数字或
-后跟数字)就计数加1,然后跳过整个整数的字符; - 直到遍历到换行符或字符串结束,停止统计。
方法二:直接从文件读取整数并判断行尾
这种方法无需一次性读取整行,适合处理大文件,通过读取每个整数后检查下一个字符是否为换行来控制范围:
#include <stdio.h> int main() { FILE *fd = fopen("test.txt", "r"); if (!fd) { perror("Failed to open file"); return 1; } int count = 0; int temp; int read_result; while ((read_result = fscanf(fd, "%d", &temp)) == 1) { count++; // 读取下一个字符,判断是否是行尾 int next_char = fgetc(fd); if (next_char == '\n' || next_char == EOF) { break; } // 如果不是行尾,把字符放回文件指针,继续读取下一个整数 ungetc(next_char, fd); } printf("第一行数字数量:%d\n", count); fclose(fd); return 0; }
逻辑说明:
- 循环用
fscanf("%d")读取整数,每次成功读取就计数加1; - 读取整数后,用
fgetc获取下一个字符,如果是换行符或文件结束,就停止循环; - 如果不是行尾,用
ungetc把字符放回文件流,保证下一次fscanf能正确读取下一个整数。
内容的提问来源于stack exchange,提问作者Harry Day
相关产品推荐
相关产品推荐

