繁体   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