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

如何初始化不定长度数组?求助修改C语言文件"is"统计程序

不定长度数组初始化 + 适配文件长度的C代码修改

嘿,我来帮你搞定这两个问题!

一、关于不定长度数组的初始化

在C语言里,处理不定长度的需求,有两种实用方式:

  • C99可变长度数组(VLA):如果你的编译器支持C99(比如GCC),可以直接用变量定义数组大小,比如:
    int size;
    // 先获取需要的大小,比如从用户输入或文件长度
    char arr[size];
    
    但要注意,VLA是在栈上分配内存,栈空间有限(通常几MB),如果需要的内存很大,容易栈溢出,所以更推荐下面的动态分配方式。
  • 动态内存分配:用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:11:57