簡體   English   中英

為什么我的 function 在 c 中反轉字符串不起作用?

[英]Why is my function to reverse string in c not working?

我正在編寫一些 C 代碼,用戶在其中輸入所需的字符串大小,然后將字符串反轉然后打印(而不是反向打印。)我還想提一下,我不想使用外部庫,重點是能夠手動完成。 我使用動態 memory 分配來創建用戶輸入大小的字符串,並稱為“反向數組”function。 在調用 function 之前一切正常。 我反轉字符串的方法遵循與反轉普通數組相同的原則,但不是移動整數,而是移動字符。 你能向我解釋我做錯了什么嗎?

我的代碼:

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

int RvsArr(char *Str, int end)
{
    int start = 0;
    char tmp;
    while (start < end)
    {
        tmp = Str[start];
        Str[start] = Str[end];
        Str[end] = tmp;
        start++;
        end--;
    }
    printf("%s", Str);
    return 0;
}

int main()
{
    int ArrSz;
    printf("Please enter array size: ");
    scanf("%i", &ArrSz);
    char *Str;
    Str = (char *)malloc(ArrSz * sizeof(char));
    printf("Please enter your string: ");
    scanf("%s", Str);
    RvsArr(Str, ArrSz);
    free(Str);
    return 0;
}

您需要反轉實際的字符串,而不是整個緩沖區。

char *RvsArr(char* Str)
{
    char *end, *wrk = Str;
    char tmp;
    if(wrk && *wrk)
    {
        end = Str + strlen(wrk) - 1;
        while(wrk < end)
        {
            tmp = *wrk;
            *wrk++ = *end;
            *end-- = tmp;
        }
    }
    return Str;
}

int main()
{
    int ArrSz;
    printf("Please enter array size: ");
    scanf(" %i", &ArrSz);
    char* Str;
    Str = malloc(ArrSz * sizeof(char));
    printf("Please enter your string: ");
    scanf(" %s", Str);
    printf("\n`%s`\n", RvsArr(Str));
    free(Str);
    return 0;
}

https://godbolt.org/z/azob5s

對於初學者,用戶可以輸入一個字符串,其大小可以小於存儲該字符串的動態分配的字符數組的大小。

所以傳遞數組的大小沒有意義。 數組的大小與輸入的字符串的大小不同。

此表達式Str[end]在 while 循環的第一次迭代中訪問超出分配數組的 memory。

而且返回類型int也沒有任何意義。

除此之外 function 不應該 output 任何東西。 function 的調用者將決定 output 結果字符串與否。

注意這個電話

scanf("%s", Str);

不安全。 最好使用 function fgets。 例如

fgets( Str, ArrSz, stdin );

在這種情況下,您需要將 function 可以 append 的新行字符'\n'刪除到輸入的字符串中。

在不使用標准字符串函數的情況下,function 可以按以下方式定義,如下面的演示程序所示。 function 不是無意義的返回類型int ,而是返回一個指向反轉字符串的第一個字符的指針。

#include <stdio.h>

char * RvsArr( char *s )
{
    char *last = s;
    
    while ( *last ) ++last;
    
    if ( last != s )
    {
        for ( char *first = s; first < --last; ++first )
        {
            char c = *first;
            *first = *last;
            *last = c;
        }
    }
    
    return s;
}

int main(void) 
{
    char s[] = "Hello World!";
    
    puts( s );
    puts( RvsArr( s ) );
    
    return 0;
}

程序 output 是

Hello World!
!dlroW olleH

如果允許您使用標准字符串函數,則 function RvsArr 可以如下所示(前提是包含 header <string.h>

char * RvsArr( char *s )
{
    char *last = s + strlen( s );
    
    if ( last != s )
    {
        for ( char *first = s; first < --last; ++first )
        {
            char c = *first;
            *first = *last;
            *last = c;
        }
    }
    
    return s;
}

字符 arrays 或 c 中的字符串(通常稱為)需要一個額外的字節來存儲 null 字符( '\o'0 )以指示字符串的結尾。 您可以在數組中存儲ArrSz - 1字符,並且ArrSz字節存儲終止字符( '\o'0 )。

int RvsArr(char* Str, int end)
{
    if (Str == 0 || end <= 1)
        return 0;

    int start = 0;
    char tmp;
    while(start < end)
    {
        tmp = Str[start];
        Str[start] = Str[--end];   // pre decrement the counter to last char
        Str[end] = tmp;
        start++;
    }
    printf("%s", Str);
    return 0;
}

或其他版本

int RvsArr(char* Str, int end)
{
    if (Str == 0 || end <= 1)
        return 0;

    int start = 0;
    int last = end - 1;
    char tmp;
    while(start < last)
    {
        tmp = Str[start];
        Str[start] = Str[last];
        Str[last] = tmp;
        start++;
        last--;
    }
    printf("%s", Str);
    return 0;
}

主要 function 的一些變化是

int main()
{
    int ArrSz;
    printf("Please enter array size: ");
    scanf("%i", &ArrSz);
    char *Str;
    Str = (char *)malloc(ArrSz * sizeof(char));
    printf("Please enter your string: ");
    scanf("%s", Str);
    Str[ArrSz] = '\0';            // Here we have no control on how many characters are read, scan is a security vulnerability becuse of this
    printf("Input=%s, len=%d\n", Str, strlen(Str));
    RvsArr(Str, strlen(Str));
    free(Str);
    return 0;
}

暫無
暫無

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

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