如何初始化不定长度数组?求助修改C语言文件"is"统计程序
不定长度数组初始化 + 适配文件长度的C代码修改
嘿,我来帮你搞定这两个问题!
一、关于不定长度数组的初始化
在C语言里,处理不定长度的需求,有两种实用方式:
- C99可变长度数组(VLA):如果你的编译器支持C99(比如GCC),可以直接用变量定义数组大小,比如:
但要注意,VLA是在栈上分配内存,栈空间有限(通常几MB),如果需要的内存很大,容易栈溢出,所以更推荐下面的动态分配方式。int size; // 先获取需要的大小,比如从用户输入或文件长度 char arr[size]; - 动态内存分配:用
malloc/calloc/realloc在堆上分配内存,这是处理未知大小场景(比如文件长度不确定)的最佳方案,内存更灵活,也能避免溢出。用完后记得用free释放内存,防止泄漏。
二、修改你的统计代码,适配任意大小的文件
你的原代码用了固定大小的char file[1000],如果文件超过1000字节就会缓冲区溢出,非常危险。下面是修改后的代码,我标注了关键修改点:
// Count of occurrence of word 'is' in file WordFile. #include<stdio.h> #include<stdlib.h> // 新增:malloc/free需要的头文件 #include<string.h> int main() { // 标准C里main应该返回int,不是void FILE *fp; long file_size; int count = 0; char *file = NULL; // 改为动态分配的指针 int times = 0; int i; // 1. 打开文件,增加错误检查 fp = fopen("../WordFile.txt", "r"); if (fp == NULL) { perror("Failed to open file"); return 1; } // 2. 获取文件大小 fseek(fp, 0, SEEK_END); // 把文件指针移到末尾 file_size = ftell(fp); // 获取当前位置(即文件总字节数) fseek(fp, 0, SEEK_SET); // 把指针移回开头,准备读取 // 3. 分配内存:文件大小 +1 用来存字符串结束符'\0' file = (char*)malloc(file_size + 1); if (file == NULL) { perror("Failed to allocate memory"); fclose(fp); return 1; } // 4. 一次性读取整个文件内容到内存 count = fread(file, 1, file_size, fp); file[count] = '\0'; // 手动添加字符串结束符 printf("Size of file is %ld bytes \n", file_size); printf("File content:\n%s\n", file); // 5. 修改统计逻辑,修复原代码的问题 // 统计"is"或"Is",且前后是分隔符(避免误统计单词内的组合,比如"This") for (i = 0; i < count; i++) { // 检查当前字符是'i'/'I',下一个是's'/'S' if ((file[i] == 'i' || file[i] == 'I') && (i+1 < count && (file[i+1] == 's' || file[i+1] == 'S'))) { int is_valid = 1; // 检查前面的字符:如果不是开头,前面必须是分隔符 if (i > 0) { char prev_char = file[i-1]; if (!(prev_char == ' ' || prev_char == ',' || prev_char == '.' || prev_char == '!' || prev_char == '?' || prev_char == '\n' || prev_char == '\t')) { is_valid = 0; } } // 检查后面的字符:要么是分隔符,要么到字符串末尾 if (i+2 < count) { char next_char = file[i+2]; if (!(next_char == ' ' || next_char == ',' || next_char == '.' || next_char == '!' || next_char == '?' || next_char == '\n' || next_char == '\t')) { is_valid = 0; } } if (is_valid) { times++; } } } printf("The word 'is' (case-insensitive) appeared %d times in the given file.\n", times); // 6. 释放内存,关闭文件 free(file); fclose(fp); return 0; }
关键修改点说明:
- 新增了文件打开和内存分配的错误检查,避免程序意外崩溃;
- 用
fseek+ftell获取文件总大小,然后用malloc分配刚好匹配的内存,彻底解决固定数组的限制; - 用
fread一次性读取文件内容,比逐字符fgetc+append高效得多; - 修复了原统计逻辑的bug:比如原代码会误统计"This"里的"is",也没正确处理文件末尾的"is";
- 遵循标准C规范,把
main返回类型改为int,去掉了过时的conio.h和getch(); - 用完内存后用
free释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Santosh
相关产品推荐
相关产品推荐

