简体   繁体   English

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

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

I am writing some C Code where the user enters the desired string size and then a string which will be reversed then printed (as opposed to being printed in reverse.) I also would like to mention that I don't want to use external libraries, the whole point of this is to be able to do it manually.我正在编写一些 C 代码,用户在其中输入所需的字符串大小,然后将字符串反转然后打印(而不是反向打印。)我还想提一下,我不想使用外部库,重点是能够手动完成。 I used dynamic memory allocation to create a string of a size inputted by the user and called a "Reverse Array" function.我使用动态 memory 分配来创建用户输入大小的字符串,并称为“反向数组”function。 Everything works fine until the function is called.在调用 function 之前一切正常。 My method for reversing the string followed the same principle as reversing a normal array but instead of moving integers around I moved characters around.我反转字符串的方法遵循与反转普通数组相同的原则,但不是移动整数,而是移动字符。 Can you explain to me what I have done wrong?你能向我解释我做错了什么吗?

My Code:我的代码:

#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;
}

You need to reverse the actual string, not the full buffer.您需要反转实际的字符串,而不是整个缓冲区。

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 https://godbolt.org/z/azob5s

For starters the user can enter a string the size of which can be less than the size of the dynamically allocated character array that stores the string.对于初学者,用户可以输入一个字符串,其大小可以小于存储该字符串的动态分配的字符数组的大小。

So passing the size of the array does not make a sense.所以传递数组的大小没有意义。 The size of the array is not the same as the size of the entered string.数组的大小与输入的字符串的大小不同。

Also this expression Str[end] access memory beyond the allocated array in the first iteration of the while loop.此表达式Str[end]在 while 循环的第一次迭代中访问超出分配数组的 memory。

And the return type int also does not make a sense.而且返回类型int也没有任何意义。

Apart from this the function should not output anything.除此之外 function 不应该 output 任何东西。 It is the caller of the function that will decide to output the result string or not. function 的调用者将决定 output 结果字符串与否。

Pay attention to that this call注意这个电话

scanf("%s", Str);

is unsafe.不安全。 It would be better to use the function fgets.最好使用 function fgets。 For example例如

fgets( Str, ArrSz, stdin );

In this case you will need to remove the new line character '\n' that the function can append to the entered string.在这种情况下,您需要将 function 可以 append 的新行字符'\n'删除到输入的字符串中。

Without using standard string functions the function can be defined the following way as it is shown in the demonstrative program below.在不使用标准字符串函数的情况下,function 可以按以下方式定义,如下面的演示程序所示。 Instead of the senseless return type int the function returns a pointer to the first character of the reversed string. 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;
}

The program output is程序 output 是

Hello World!
!dlroW olleH

If you are allowed to use standard string functions then the function RvsArr can look the following way (provided that the header <string.h> is included)如果允许您使用标准字符串函数,则 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;
}

Character arrays or string in c(as it is generally referred to) requires one extra byte which store null character ( '\o' or 0 ) to indicate the end of string.字符 arrays 或 c 中的字符串(通常称为)需要一个额外的字节来存储 null 字符( '\o'0 )以指示字符串的结尾。 You can store ArrSz - 1 character in your array and ArrSz byte stores the termination character( '\o' or 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;
}

or in other version或其他版本

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;
}

And some changes in main function are主要 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