C语言字符串单词旋转功能异常,请求代码排查修复
字符串单词旋转功能异常排查与修复
问题描述
尝试实现字符串单词旋转功能:将最后一个单词移至最前,其余单词顺序后移。输入$(echo -ne ' AkjhZ zLKIJz , 23y')时,预期输出为23y AkjhZ zLKIJz ,$,但当前代码无法正常运行。
现有代码
#include <stdio.h> #include <string.h> void rotate_words(char *str) { char *token = strtok(str, " "); char *words[100]; int count = 0; while (token != NULL) { words[count++] = token; token = strtok(NULL, " "); } printf("%s ", words[count-1]); for (int i = 0; i < count-1; i++) { printf("%s ", words[i]); } printf("\n"); } int main(int argc, char *argv[]) { if (argc == 1) { printf("\n"); } else { char *str = argv[1]; rotate_words(str); } return 0; }
问题分析
- 分隔符范围不足:输入包含制表符(
\t),但strtok仅以空格为分隔符,导致制表符无法被识别,会将\tAkjhZ这类带制表符的内容当成单个单词处理,无法正确提取目标单词。 - 修改只读内存:
argv[1]指向程序参数的只读内存区域,strtok会修改原字符串(用\0替换分隔符),直接操作会触发未定义行为,导致程序异常。 - 输出格式偏差:当前代码每个单词后都添加空格,会导致结尾多一个空格,且未匹配预期输出的结尾
$。 - 边界情况缺失:未处理输入为空或只有单个单词的场景,存在数组越界风险。
修复后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> void rotate_words(char *str) { char *token = strtok(str, " \t"); // 同时识别空格和制表符作为分隔符 char *words[100]; int count = 0; // 提取所有单词,避免数组越界 while (token != NULL && count < 99) { words[count++] = token; token = strtok(NULL, " \t"); } if (count == 0) { printf("\n"); return; } // 输出最后一个单词 printf("%s", words[count-1]); // 输出其余单词,前置空格避免结尾冗余 for (int i = 0; i < count-1; i++) { printf(" %s", words[i]); } printf("$\n"); // 匹配预期输出的结尾标识 } int main(int argc, char *argv[]) { if (argc == 1) { printf("\n"); return 0; } // 复制参数到可写内存,避免修改只读区域 char *str = malloc(strlen(argv[1]) + 1); if (str == NULL) { perror("malloc failed"); return 1; } strcpy(str, argv[1]); rotate_words(str); free(str); // 释放动态分配的内存 return 0; }
修复要点说明
- 扩展分隔符:将
strtok的分隔符改为" \t",同时支持空格和制表符拆分单词。 - 内存安全处理:用
malloc复制参数内容到可写内存,避免修改只读内存引发的异常。 - 输出格式优化:调整输出逻辑,避免结尾冗余空格,添加预期的
$结尾。 - 边界防护:添加空输入判断和数组越界限制,提升程序健壮性。
- Shell输入提示:运行时需用双引号包裹输入,确保制表符被正确传递:
./program "$(echo -ne ' AkjhZ zLKIJz , 23y')"
内容的提问来源于stack exchange,提问作者azerty1975
相关产品推荐
相关产品推荐

