使用fgets获取字符串后在单词间插入#时出现访问越界错误
问题排查与修复
错误原因
导致访问违例的核心问题有4个:
replaceChar函数的循环条件存在严重类型错误:current_pos + strlen(current_pos)是内存地址,直接和字符常量'\n'比较逻辑完全失效,无法阻止内存越界访问。strtok切割字符串时会将所有分隔符(空格)替换为'\0',你调用replaceChar全局替换'\0'为'#'时,会把字符串末尾的终止符'\0'也替换掉,导致字符串没有结束标识。后续strchr会持续向后读取超出合法边界的内存,直接触发访问违例。replaceChar每次都从字符串开头调用strchr查找目标字符,替换后仍然从头查找,不仅效率极低,在丢失字符串终止符后会无限遍历非法内存。- 原有逻辑无法满足需求:如果原字符串存在连续空格,
strtok会生成多个连续'\0',全部替换为'#'会出现连续#,不符合「单词之间插入单个#」的要求。
修复方案
以下是可直接使用的原地修改实现,自动处理开头空格、结尾空格、连续空格场景,不会触发内存越界:
// 调用前先处理fgets读取的换行符 char buf[1024]; fgets(buf, sizeof(buf), stdin); buf[strcspn(buf, "\n")] = '\0'; // 移除末尾换行符 // 插入#的核心函数 char* addNumberSign(char* string) { if (string == NULL || *string == '\0') return string; char* write_ptr = string; char* read_ptr = string; // 跳过开头所有空格 while (*read_ptr == ' ') read_ptr++; while (*read_ptr != '\0') { // 复制当前完整单词 while (*read_ptr != ' ' && *read_ptr != '\0') { *write_ptr++ = *read_ptr++; } // 跳过当前单词后的所有连续空格 while (*read_ptr == ' ') read_ptr++; // 还有后续单词则插入# if (*read_ptr != '\0') { *write_ptr++ = '#'; } } // 补字符串终止符 *write_ptr = '\0'; return string; }
如果你坚持要基于strtok实现,需要预先记录所有单词的位置,再手动插入#,不能直接全局替换'\0'。
内容的提问来源于stack exchange,提问作者Roee
相关产品推荐
相关产品推荐

