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
相关产品推荐
相关产品推荐

