簡體   English   中英

C在void函數中的單個字符串中反轉兩個單詞

[英]C reverse two words in a single string in a void function

我的函數應反轉兩個字符串-名字和姓氏。 因此,John Smith的輸出應該是Smith John。 問題是,它應該是void函數。 所以我想應該修改全局數組。 我試圖對其進行編碼-我附加了代碼,但是它不起作用。 我的陣列保持不變。 我認為結論中的某個地方有錯誤,我試圖覆蓋結論中的初始數組“名稱”,這是行不通的。 對錯誤有任何想法嗎?

#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] = '\0';
        }
        else if (firstName)
            first[i] = name[i];
        else {
            second[index] = name[i];
            index++;
        }
    }
    second[index] = ' ';
    second[index+1] = '\0';
    name = strcat(second, first);
}

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

你做錯了什么? 您無法返回修改后的字符串。 替換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;
}

對錯誤有任何想法嗎?

在主函數中,我們將名稱傳遞給reverse(),其中名稱包含數組名稱的地址[]例如說P1。

reverse(name); // name is P1

在函數中,反向名稱將包含數組名稱的地址,即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

現在,當我們返回main()時, 名稱仍包含數組的地址,即P1(函數上下文已完成,因此它是局部變量),而不是最終字符串的地址,即P2。

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

中間緩沖區很無聊。 這是一個無限制的按字符交換器:

#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. 執行所需的操作。

現在,建議的代碼為:

#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,  '\0', strlen( name ) );
    memset( genSecond, '\0', 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM