使用指针反转C语言字符串遇问题,请求代码故障排查指导
我来帮你揪出这段代码里的问题,几个关键地方出错了,咱们一个个拆解:
1. scanf格式字符串多了个多余的s
你写的scanf("%[^\n]s", sentence);有问题——%[^\n]本身就是完整的格式说明符,用来读取直到换行符的所有字符,后面加的s完全是多余的,会导致scanf匹配失败,读不到输入的字符串。应该改成:
scanf("%[^\n]", sentence);
另外补个小细节:如果程序运行前输入缓冲区里留了换行符(比如之前的输入操作残留的),这个scanf会直接读空字符串。可以改成scanf(" %[^\n]", sentence);(注意前面的空格,它会自动跳过所有空白字符),或者在scanf前加getchar();清空缓冲区。
2. 指针位置错了,还越界访问了
计算完字符串长度后,你的sPtr已经跑到字符串末尾的'\0'位置了(因为循环条件是*sPtr != '\0',直到指针指向终止符才停下)。然后你在for循环里用*(sPtr + 1),这已经超出了字符串的内存范围,属于未定义行为,要么输出乱码,要么直接让程序崩溃。
而且循环的起始值也不对:字符串长度是length,数组下标是从0到length-1,你从i = length开始,第一个访问的就是sentence[length],也就是那个'\0',根本不是你要的有效字符。
给你两个修复后的版本
版本1:用指针从末尾往回遍历
调整指针位置,让它回到最后一个有效字符,然后往前遍历:
#include <stdio.h> int main(void) { char sentence[100]; printf("Enter any string: "); // 修复scanf格式,加空格跳过空白字符 scanf(" %[^\n]", sentence); char *sPtr = sentence; int length = 0; printf("Original string = %s\n", sentence); // 计算长度后,sPtr指向字符串末尾的'\0' while (*sPtr != '\0') { ++length; ++sPtr; } printf("Reverse string = "); // 把指针回退一步,指向最后一个有效字符 sPtr--; // 从最后一个字符遍历到第一个 while (sPtr >= sentence) { printf("%c", *sPtr); sPtr--; } puts(""); return 0; }
版本2:直接用数组下标访问(更直观)
如果觉得指针移动容易搞混,直接用数组下标来反转更简单:
#include <stdio.h> int main(void) { char sentence[100]; printf("Enter any string: "); scanf(" %[^\n]", sentence); int length = 0; printf("Original string = %s\n", sentence); // 先算出字符串长度 while (sentence[length] != '\0') { ++length; } printf("Reverse string = "); // 从最后一个有效字符(下标length-1)开始,遍历到第一个字符(下标0) for (int i = length - 1; i >= 0; --i) { printf("%c", sentence[i]); } puts(""); return 0; }
额外小提示
sentence[100]最多只能存99个有效字符加一个终止符,输入太长会导致缓冲区溢出。如果是实际项目里,更推荐用fgets来读取字符串,比如fgets(sentence, sizeof(sentence), stdin);,不过要注意fgets会把换行符也读进去,需要手动处理掉(比如把换行符换成'\0')。
内容的提问来源于stack exchange,提问作者Jordan

