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

如何跳过NULL文件?C语言命令行工具代码修改咨询

问题:处理命令行文件参数时跳过NULL文件继续执行

我的代码会遍历命令行参数,把alice.txt存入nameArray[0],把anh.txt存入nameArray[1]。执行./wc alice.txt anh.txt时能正常统计两个文件的行数、单词数和字符数,但执行./wc anh.txt时会弹出"NULL FILE"提示并退出程序,推测是nameArray[0]为NULL导致的。希望修改代码,让程序不退出,而是跳过NULL的索引继续执行。

现有代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>

// 假设print_counts函数已实现
void print_counts(int *argArray, int *counts, char *filename);

int main(int argc, char **argv)
{
    int argArray[argc];
    char *nameArray[argc];


    for (int i = 1; i < argc; i ++)
    {
        if (strcmp(argv[i], "-l") == 0)
        {
            argArray[0] = 1;
        }
        if (strcmp(argv[i], "-w") == 0)
        {
            argArray[1] = 1;
        }
        if (strcmp(argv[i], "-c") == 0)
        {
            argArray[2] = 1;
        }
        if (strcmp(argv[i], "alice.txt") == 0)
        {
            nameArray[0] = "alice.txt";
        }
        if (strcmp(argv[i], "anh.txt") == 0)
        {
            nameArray[1] = "anh.txt";
        }

        if ((strcmp(argv[i], "-l") != 0) && (strcmp(argv[i], "-c") != 0 ) && (strcmp(argv[i], "-w") != 0 ) && (strcmp(argv[i], "-w") != 0) && (strcmp(argv[i], "alice.txt") != 0) && (strcmp(argv[i], "anh.txt") != 0))
        {
            printf("%s is an invalid argument or file\n", argv[i]);
        }
    }
    if ((argArray[0] != 1) && (argArray[1] != 1) && (argArray[2] != 1))
    {
        argArray[0] = 1;
        argArray[1] = 1;
        argArray[2] = 1;
    }

    int *myArrayAlice = get_counts2(nameArray[0]);
    print_counts(argArray, myArrayAlice, *nameArray);
    printf(" alice.txt\n");

    int *myArrayAnh = get_counts(nameArray[1]);
    print_counts(argArray,myArrayAnh, *nameArray);
    printf(" anh.txt\n");
    int *myArrayTotal2 = get_counts2(nameArray[1]);
    print_counts(argArray, myArrayTotal2, *nameArray);
    printf(" total\n");
    return 0;
}
int *get_counts(char *filename)
{

    FILE *file = fopen(filename, "r");

    if (file == NULL)
    {
        printf("NULL FILE");
        //exit(1);
    }

    int c;
    bool whitespace = true;
    int *arr = calloc(3,sizeof(int));
    for(;;)
    {
        c = fgetc(file);
        if (c == EOF)
        {
            break;
        }
        else if (c == '\n')
        {
            arr[0]++;
        }
        else if (whitespace && !isspace(c))
        {
            arr[1]++;
            whitespace = false;
        }
        else if (!whitespace && isspace(c))
        {
            whitespace = true;
        }
        arr[2]++;
    }
    fclose(file);
    return arr;
}
int *get_counts2(char *filename)
{

    FILE *file = fopen(filename, "r");

    if (file == NULL)
    {
        printf("NULL FILE");
        //exit(1);
    }

    int c;
    bool whitespace = true;
    static int arr[3] = {0,0,0};
    for(;;)
    {
        c = fgetc(file);
        if (c == EOF)
        {
            break;
        }
        else if (c == '\n')
        {
            arr[0]++;
        }
        else if (whitespace && !isspace(c))
        {
            arr[1]++;
            whitespace = false;
        }
        else if (!whitespace && isspace(c))
        {
            whitespace = true;
        }
        arr[2]++;
    }
    fclose(file);
    return arr;
}

修改方案

1. 初始化数组,消除未定义行为

原代码中argArray和nameArray未初始化,会产生随机值,改为固定大小并初始化:

// 只处理-l/-w/-c三个选项,固定大小3并初始化为0
int argArray[3] = {0};
// 只存两个目标文件,固定大小2并初始化为NULL
char *nameArray[2] = {NULL};

2. 跳过NULL文件,不执行统计逻辑

在调用统计函数前,先判断文件名是否为NULL,仅非NULL时才执行统计和打印,同时修复print_counts的参数错误:

// 处理alice.txt
if (nameArray[0] != NULL) {
    int *myArrayAlice = get_counts2(nameArray[0]);
    if (myArrayAlice != NULL) {
        print_counts(argArray, myArrayAlice, nameArray[0]);
        printf(" alice.txt\n");
        free(myArrayAlice); // 释放动态分配的内存
    }
}

// 处理anh.txt
if (nameArray[1] != NULL) {
    int *myArrayAnh = get_counts(nameArray[1]);
    if (myArrayAnh != NULL) {
        print_counts(argArray, myArrayAnh, nameArray[1]);
        printf(" anh.txt\n");
        free(myArrayAnh); // 释放get_counts中calloc的内存
    }
}

3. 修复统计函数的NULL处理逻辑

原函数中文件名NULL或文件打开失败时,仍会执行后续代码导致崩溃,修改后直接返回NULL并终止函数:

int *get_counts(char *filename)
{
    // 先判断文件名是否为NULL
    if (filename == NULL) {
        return NULL;
    }
    FILE *file = fopen(filename, "r");

    if (file == NULL)
    {
        printf("无法打开文件: %s\n", filename);
        return NULL;
    }

    int c;
    bool whitespace = true;
    int *arr = calloc(3,sizeof(int));
    for(;;)
    {
        c = fgetc(file);
        if (c == EOF)
        {
            break;
        }
        else if (c == '\n')
        {
            arr[0]++;
        }
        else if (whitespace && !isspace(c))
        {
            arr[1]++;
            whitespace = false;
        }
        else if (!whitespace && isspace(c))
        {
            whitespace = true;
        }
        arr[2]++;
    }
    fclose(file);
    return arr;
}

// 修改get_counts2,去掉静态数组改为动态分配,避免多次调用累加错误
int *get_counts2(char *filename)
{
    if (filename == NULL) {
        return NULL;
    }
    FILE *file = fopen(filename, "r");

    if (file == NULL)
    {
        printf("无法打开文件: %s\n", filename);
        return NULL;
    }

    int c;
    bool whitespace = true;
    int *arr = calloc(3,sizeof(int)); // 改为动态分配
    for(;;)
    {
        c = fgetc(file);
        if (c == EOF)
        {
            break;
        }
        else if (c == '\n')
        {
            arr[0]++;
        }
        else if (whitespace && !isspace(c))
        {
            arr[1]++;
            whitespace = false;
        }
        else if (!whitespace && isspace(c))
        {
            whitespace = true;
        }
        arr[2]++;
    }
    fclose(file);
    return arr;
}

4. 修复总和统计逻辑

原代码中总和计算错误,改为累加所有有效文件的统计结果:

int total[3] = {0};
// 累加alice.txt的统计结果
if (nameArray[0] != NULL) {
    int *alice = get_counts2(nameArray[0]);
    if (alice != NULL) {
        total[0] += alice[0];
        total[1] += alice[1];
        total[2] += alice[2];
        free(alice);
    }
}
// 累加anh.txt的统计结果
if (nameArray[1] != NULL) {
    int *anh = get_counts(nameArray[1]);
    if (anh != NULL) {
        total[0] += anh[0];
        total[1] += anh[1];
        total[2] += anh[2];
        free(anh);
    }
}
// 只有存在有效统计结果时才打印总和
if (total[0] != 0 || total[1] != 0 || total[2] != 0) {
    print_counts(argArray, total, "total");
    printf(" total\n");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 20:21:42