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

C语言嵌套调用字符串匹配函数时返回值异常问题排查

C语言num_matches函数文件读取场景返回异常问题

问题描述

我编写的num_matches函数用于统计word字符串中匹配letters字符集的字符总数,函数实现如下:

int num_matches(char* word, char* letters) {
    char scrabble[128];
    strcpy(scrabble, letters);
    int num = 0;

    for (int i = 0; i < strlen(word); i++) {
        if (strchr(letters, word[i]) == NULL) {
            return -1;
        }

        for (int j = 0; j < strlen(letters); j++) {
            if (word[i] == letters[j]) {
                num++;
                scrabble[j] = '\0';
                break;
            }
        }

    }
    return num;
}

单独传入参数"QWOP"、"QWOP"调用该函数时可正确返回4,但在如下read_words函数内部调用时,即便调试打印显示buff和letters的值均为"QWOP",所有调用均返回错误值,结果不符合预期。

void read_words(int num_count[128], char* (*word_idx)[128], int argc, char** argv) {
    FILE* fp = fopen(argv[1], "r");
    char* letters = argv[2];

    int idx = 0;
    char buff[128];
    int result = 0;
    while (fgets(buff, 128, fp) != NULL) {
        printf("buff:%s letters:%s\n", buff, letters);
        result = num_matches(buff, letters);
        printf("result: %d\n", result);
        num_count[idx] = result;
        char* word = malloc(strlen(buff) + 1);
        strcpy(word, buff);
        (*word_idx)[idx] = word;
        idx++;
        result = 0;
    }

    fclose(fp);
}

实际运行输出如下:

buff:QWOP
 letters:QWOP
result: -1

使用的测试txt文件内容如下:

ABC
DEFG
QWOP
QWOP
QUOKKA
QUOLL
QUASH
QUANDONG

已知fgets读取时遇到换行符会终止,且测试文本中无空格,初步判断buff读取逻辑无问题,无法定位返回值异常的原因。

故障原因

  • 直接触发返回-1的原因是fgets()会将行尾的换行符\n一同存入buff缓冲区。从运行输出就能看到证据:printf的格式串是"buff:%s letters:%s\n",正常情况下 letters:QWOP应该和buff:QWOP在同一行,但实际输出中它出现在下一行,就是buff末尾自带的\n触发了换行。
  • 当num_matches遍历到buff末尾的\n字符时,执行strchr(letters, word[i])查找换行符,而传入的letters是"QWOP",不包含换行符,因此直接触发return -1的分支,返回错误值。
  • 单独测试时手动传入的"QWOP"字符串末尾没有换行符,所以可以正确返回4,两个场景的输入差异就在这个隐藏的换行符上。
  • 额外说明:当前num_matches本身还有逻辑缺陷,声明scrabble数组的初衷是记录已匹配的字符,但实际匹配判断全程用的是原letters数组,根本没有校验scrabble的标记位,遇到letters有重复字符的场景会计数错误,但这不是导致本次返回-1的原因。

修复方法

在fgets读取到buff之后,立刻添加代码去掉末尾的换行符即可:

while (fgets(buff, 128, fp) != NULL) {
    // 去除fgets留存的行尾换行符
    buff[strcspn(buff, "\n")] = '\0';
    printf("buff:%s letters:%s\n", buff, letters);
    // 后续原有逻辑保持不变
    result = num_matches(buff, letters);
    // ...
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:18:24