C语言编程求助:ASCII升序字符序列中间字符替换为减号
C语言连续字符序列替换问题的修复方案
原代码核心问题
- 赋值与比较运算符混淆:多处
if (sequence = false)是赋值操作而非逻辑判断,应改为==。 - 输入读取不完整:
scanf("%s")遇到空格就停止,无法处理示例中带空格的输入,需替换为fgets。 - 数组越界访问:循环条件
i < slen会导致遍历到字符串最后一位时,访问string[i+1]超出数组范围,需调整为i < slen - 1。 - 错误的字符串修改逻辑:
string[j] = ''是无效语法(空字符应为'\0'),且直接设置空字符会截断字符串,正确方式是将后续字符前移覆盖中间冗余部分。 - 未处理末尾连续序列:当字符串末尾是连续序列时,循环结束后不会触发替换逻辑,需额外处理。
- 缺少序列长度判断:只有长度≥3的连续序列才需要替换(如
abc→a-c,ab无需处理),原代码未做此判断。
修正后的代码
#include <stdio.h> #include <string.h> typedef enum { false, true } bool_enum; #define MAX_INPUT_LENGTH 80 void sequence_replace(char string[]); int main() { char input_str[MAX_INPUT_LENGTH]; printf("请输入待处理的字符串:"); // 使用fgets读取包含空格的完整输入,同时去除末尾的换行符 fgets(input_str, MAX_INPUT_LENGTH, stdin); input_str[strcspn(input_str, "\n")] = '\0'; sequence_replace(input_str); printf("处理后的字符串:%s\n", input_str); return 0; } void sequence_replace(char string[]) { int slen = strlen(string); bool_enum in_sequence = false; int seq_start = 0; for (int i = 0; i < slen - 1; i++) { // 检查当前字符与下一个是否连续 if (string[i] + 1 == string[i+1]) { if (!in_sequence) { in_sequence = true; seq_start = i; } } else { if (in_sequence) { // 计算序列长度,只有长度≥3才处理 int seq_length = i - seq_start + 1; if (seq_length >= 3) { // 将起始位置的下一个字符设为'-' string[seq_start + 1] = '-'; // 将序列结束后的字符向前移动,覆盖中间冗余部分 memmove(&string[seq_start + 2], &string[i + 1], slen - i); // 更新字符串长度,因为字符被移除了 slen -= (i - (seq_start + 1)); // 重置i的位置,从新的序列起始后开始遍历 i = seq_start + 1; } in_sequence = false; } } } // 处理字符串末尾的连续序列 if (in_sequence) { int seq_length = slen - seq_start; if (seq_length >= 3) { string[seq_start + 1] = '-'; memmove(&string[seq_start + 2], &string[slen], 1); // 移动末尾的'\0' slen -= (slen - (seq_start + 2)); } } }
关键修改说明
- 输入处理:用
fgets读取完整输入,再用strcspn去除换行符,确保能处理带空格的字符串。 - 运算符修正:将所有赋值判断改为
==,保证逻辑正确。 - 越界避免:循环条件改为
i < slen - 1,防止访问超出字符串范围。 - 字符串修改优化:使用
memmove高效移动字符,覆盖中间冗余部分,同时更新字符串长度,确保后续遍历正确。 - 末尾序列处理:循环结束后额外检查是否处于序列中,处理末尾的连续字符。
- 序列长度判断:仅对长度≥3的序列进行替换,符合示例要求。
内容的提问来源于stack exchange,提问作者Max Ilyouchenko
相关产品推荐
相关产品推荐

