C语言char指针子串匹配程序单字符匹配异常问题求助
单字符子串统计错误的修复方案
原程序代码
int vorkommen(const char* s, const char* m) { int lengthS = 0; int lengthM = 0; while (s[lengthS] != '\0') { lengthS++; } while (m[lengthM] != '\0') { lengthM++; } char textS[lengthS - 1]; char textM[lengthM - 1]; for(int i = 0; i < lengthS; i++) { textS[i] = s[0]; s++; } for(int i = 0; i < lengthM; i++) { textM[i] = m[0]; m++; } int match = 0; for(int i = 0; i < lengthS; i++) { for(int j = 0; j <= lengthM; j++) { if(j == lengthM) { match++; } else if(textS[i + j] != textM[j]) { break; } } } return match; } void Aufgabe_7() { char first[256]; char second[256]; cin.getline(first, sizeof(first)); cin.getline(second, sizeof(second)); int test = vorkommen(first, second); cout << test; } int main() { Aufgabe_7(); return 0; }
问题根源分析
数组大小定义错误:
原代码中char textS[lengthS - 1];和char textM[lengthM - 1];多减了1。lengthS和lengthM是字符串的有效字符数(不含终止符'\0'),数组需要容纳所有字符,应直接用lengthS和lengthM作为大小。当子串是单字符时,lengthM=1,原数组大小为0,属于非法零长度数组,访问时会触发内存越界,导致未定义行为。匹配循环边界错误:
外层循环for(int i = 0; i < lengthS; i++)范围过大。子串长度为lengthM时,起始索引i的最大有效值应为lengthS - lengthM,否则i + j会超出textS的数组范围,引发越界访问。冗余的字符串复制:
原代码复制字符串的逻辑完全没必要,直接使用传入的原指针s和m进行匹配即可,额外复制徒增内存开销和出错风险。
修复后的代码
#include <iostream> using namespace std; int vorkommen(const char* s, const char* m) { int lengthS = 0; int lengthM = 0; // 计算主串长度 while (s[lengthS] != '\0') { lengthS++; } // 计算子串长度 while (m[lengthM] != '\0') { lengthM++; } // 处理特殊情况:子串为空或子串比主串长,直接返回0 if (lengthM == 0 || lengthM > lengthS) { return 0; } int match = 0; // 外层循环:起始索引最大为lengthS - lengthM,避免越界 for (int i = 0; i <= lengthS - lengthM; i++) { bool isMatch = true; for (int j = 0; j < lengthM; j++) { if (s[i + j] != m[j]) { isMatch = false; break; } } if (isMatch) { match++; } } return match; } void Aufgabe_7() { char first[256]; char second[256]; cin.getline(first, sizeof(first)); cin.getline(second, sizeof(second)); int test = vorkommen(first, second); cout << test << endl; } int main() { Aufgabe_7(); return 0; }
修复说明
- 移除冗余的字符串复制逻辑,直接使用原指针匹配,简化代码并避免数组越界风险。
- 调整外层循环边界条件,确保
i + j不会超出主串范围。 - 添加特殊情况处理,避免无效循环。
- 用
isMatch标志优化匹配逻辑的可读性,替代原代码中j == lengthM的判断方式。
内容的提问来源于stack exchange,提问作者Marakaner
相关产品推荐
相关产品推荐

