字符串的最后一个反转单词正在换行,为什么?

Last reversed word of a string is shifting to a newline, why?

我正在尝试在 C 中逐字反转字符串。到目前为止,我成功地反转了单词,但是有一个换行问题我不明白为什么会发生。 代码如下。

#include <stdio.h>
void reverse_string(char input[], int start, int end)
{
    char temp;
    while (start < end)
    {
        temp = input[start];
        input[start] = input[end];
        input[end] = temp;
        start++;
        end--;
    }
}
int main()
{
    char input[100];
    printf("Input > ");
    fgets(input, 100, stdin);
    int start = 0, end = 0;
    while (input[end])
    {
        for (end = start; input[end] && input[end] != ' '; end++);
        reverse_string(input, start, end - 1);
        start = end + 1;
    }
    printf("%s", input);
    return 0;
}

如果输入“今天是晴天”,结果将是

yadoT si a ynnu
.yad

我要的是

yadoT si a ynnu .yad

我应该如何编辑上面的代码,以便每个颠倒的单词都在同一行?

如评论中所述,调用 fgets 返回的字符串将包含终止换行符。由于该换行符不是 actual space 字符,因此它被视为最后一个单词的一部分。要处理此问题,您可以删除该换行符,如链接帖子中所示。

或者(也许更简单),只需将您的 input[end] != ' ' 测试更改为检查 any whitespace 字符的测试; the isspace() function(在“ctype.h”头文件中声明)将为您执行此操作。所以,只需将 one-line(空)for 循环更改为:

for (end = start; input[end] && !isspace((unsigned char)input[end]); end++) {}

请注意,我已将您的“空语句”; 循环体更改为 {},这使得您的代码的任何未来读者更清楚您实际上打算使用空循环体,而不是犯 typo-style 错误;它还可以防止某些编译器出现警告。另外,关于为什么我在 isspace 的参数上使用 (unsigned char) 转换,请参阅:Do I need to cast to unsigned char before calling toupper(), tolower(), et al.?