使用getw()读取文件整数时遇26提前终止循环的问题求助
问题分析与解决方案
问题根源
- 你用
putw()写入整数,但打开文件用的是文本模式("r")。在Windows平台下,ASCII值26对应Ctrl+Z,是文本模式的文件结束标记,getw()读到这个值时会直接返回EOF,导致循环提前终止。 getw()和putw()本质是用于二进制数据读写的函数,和文本模式的文件操作不兼容——文本模式会对特殊字符(比如EOF、换行)做自动转换,破坏原始整数数据。
解决方案
1. 改用二进制模式打开文件
将读文件的fopen参数改为"rb",写文件时对应改成"wb",这样系统不会对文件内容做文本转换,26会被当作普通整数处理:
void readfile() { FILE *f; // 用二进制模式打开 f = fopen("INTEGERS.DAT", "rb"); int num, xar=1; if (f==NULL){ printf("NO file detected.\n"); exit(0); } else { while((num = getw(f)) != EOF) { printf("%d ", num); if ( xar % 7 == 0) { printf("\n"); } xar++; } } fclose(f); }
同时,写入文件的代码也要对应改成二进制模式:
void writefile() { FILE *f = fopen("INTEGERS.DAT", "wb"); if (f == NULL) { perror("Failed to open file"); exit(1); } // 示例:写入包含26的整数序列 int nums[] = {1,2,3,26,5,6,7,8,9,10}; for (int i=0; i<sizeof(nums)/sizeof(int); i++) { putw(nums[i], f); } fclose(f); }
2. 更推荐:用fread/fwrite替代getw/putw
getw和putw属于过时的函数,行为在不同平台可能有差异。用标准的二进制读写函数fread和fwrite更可靠:
void readfile() { FILE *f = fopen("INTEGERS.DAT", "rb"); if (f == NULL) { printf("NO file detected.\n"); exit(0); } int num; int xar = 1; // 每次读取一个int大小的数据,成功读取则继续循环 while (fread(&num, sizeof(int), 1, f) == 1) { printf("%d ", num); if (xar % 7 == 0) { printf("\n"); } xar++; } fclose(f); } // 对应的写入函数 void writefile() { FILE *f = fopen("INTEGERS.DAT", "wb"); if (f == NULL) { perror("Failed to open file"); exit(1); } int nums[] = {1,2,3,26,5,6,7,8,9,10}; fwrite(nums, sizeof(int), sizeof(nums)/sizeof(int), f); fclose(f); }
为什么fscanf也没用?
因为fscanf是文本模式的输入函数,同样会把文本中的ASCII 26识别为EOF标记,导致提前终止。必须用二进制模式处理二进制存储的整数。
内容的提问来源于stack exchange,提问作者noRobotNoPro
相关产品推荐
相关产品推荐

