C 在 void 函数中反转单个字符串中的两个单词

C reverse two words in a single string in a void function

我的函数应该反转两个字符串 - 名字和姓氏。所以 John Smith 的输出应该是 Smith John。问题是,它应该是 void 函数。所以我想应该修改全局数组。我试图对其进行编码 - 我附加了代码,但它不起作用。我的阵列保持不变。我认为结论的某个地方是错误的,我试图覆盖初始数组 'name' 作为结论,它不起作用。请问有什么错误的想法吗?

#include <stdio.h>
#include <string.h>
void reverse(char *name) {
    int index = 0;
    char first[20];
    char second[20];
    bool firstName = true;
    for (int i = 0; i < strlen(name); i++) {
        if (name[i] == ' ') {
            firstName = false;
            first[i] = '[=10=]';
        }
        else if (firstName)
            first[i] = name[i];
        else {
            second[index] = name[i];
            index++;
        }
    }
    second[index] = ' ';
    second[index+1] = '[=10=]';
    name = strcat(second, first);
}

int main() {
    char name[] = "John Smith";
    printf("originally: %s\n", name);
    reverse(name);
    printf("reversed: %s\n", name);
}

Any idea about mistake please?

在 main 函数中,我们将 name 传递给 reverse() 这里 name 包含数组名称的地址[] 例如 P1。

reverse(name); // name is P1

在函数 reverse name 中将包含数组 name 的地址,即 P1

void reverse(char *name) { // name still p1

并且此名称是函数的局部名称。

这里,让我们先来了解一下strcat。 正如手册页所建议的那样:

char *strcat(char *dest, const char *src);
The strcat() function return a pointer to the resulting string dest.

如以下代码所示,我们正在更新 name。现在名称将包含指向目标字符串的指针,例如 p2。

name = strcat(second, first); // name has become p2

现在当我们 return 到 main() 时,name 仍然包含数组的地址,即 P1(函数上下文完成,局部变量也完成)而不是最终字符串的地址,即 P2.

reverse(name); // name is p1
printf("reversed: %s\n", name); // name is p1

你做错了什么?您未能 return 修改后的字符串。将 name = strcat(second, first); 替换为:

strcpy(name, second);
strcat(name, first);

这是一个非常简单的替代解决方案:

#include <stdio.h>

void reverse(char *buf) {
    char first[20], last[20];
    if (sscanf(buf, "%19s%19s", first, last) == 2) {
        sprintf(buf, "%s %s", last, first);
    }
}

int main() {
    char name[] = "John Smith";
    printf("originally: %s\n", name);
    reverse(name);
    printf("reversed: %s\n", name);
    return 0;
}

中间缓冲区很无聊。这是一个没有大小限制的 char-by-char 交换器:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void reverse(char *name) {
    char c1, c2;
    size_t pos1 = 0, pos2 = 0, pos_sep, name_len, count;

    {
        char *p_sep = strchr(name, ' ');

        if (!p_sep) {
            return;
        }
        pos_sep = p_sep - name;
        name_len = pos_sep + strlen(p_sep);
    }

    c1 = name[0];
    for (count = name_len; count != 0; count--) {
        {
            if (pos2 < pos_sep)  {
                pos2 = pos2 + name_len - pos_sep;
            } else if (pos2 > pos_sep) {
                pos2 = pos2 - (pos_sep + 1);
            } else {
                pos2 = name_len - (pos_sep + 1);
            }
            c2 = name[pos2];
            name[pos2] = c1;
            c1 = c2;
            if (pos2 == pos1) {
                pos1++;
                pos2 = pos1;
                c1 = name[pos1];
            }
        }
        //fprintf(stderr, "%s\n", name);
    }
}

static void _test(char *name, const char *expected) {
    reverse(name);
    if (0 != strcmp(expected, name)) {
        fprintf(stderr, "something wrong\n");
        exit(1);
    }
}

#define test(name, expected) do { \
    static char buf[] = name; \
    _test(buf, expected); \
} while(0)

int main()
{

    test("abc", "abc");

    test("abcde 123", "123 abcde");
    test("abc 12345", "12345 abc");

    test("ab 12", "12 ab");
    test("a 12", "12 a");
    test("ab 1", "1 ab");
    test("a ", " a");
    test(" 1", "1 ");
    test(" ", " ");
    test("ab 123", "123 ab");
    test("ab  12", " 12 ab");
    test("abc 1234", "1234 abc");

    test("abc 12345", "12345 abc");
    test("abcd 1234", "1234 abcd");
    test("abcd 12345", "12345 abcd");

    fprintf(stderr, "all fine\n");
    return 0;
}

以下建议代码:

  1. 干净地编译
  2. 消除不必要的局部变量
  3. 利用 C
  4. 的可变长度数组特性
  5. 执行所需的操作。

现在,建议的代码:

#include <stdio.h>
#include <string.h>

// prototypes
void reverse(char *name);

int main( void )
{
    char name[] = "John Smith";
    printf("originally: %s\n", name);
    reverse(name);
    printf("reversed: %s\n", name);
}


void reverse(char *name)
{
    char genFirst[ strlen( name )+1 ];
    char genSecond[ strlen( name )+1 ];

    memset( genFirst,  '[=10=]', strlen( name ) );
    memset( genSecond, '[=10=]', strlen( name ) );

    size_t i;
    for ( i = 0; name[i] && name[i] != ' '; i++ )
    {
        genFirst[i] = name[i];
    }

    i++;

    for ( size_t j = 0; name[j]; j++ )
    {
        genSecond[ j ] = name[ i+j ];
    }

    genSecond[i] = ' ';

    strcpy( name, genSecond );
    strcat( name, genFirst );
}

结果输出是:

originally: John Smith
reversed: Smith John