简体   繁体   English

没有库函数的C中的反向字符串函数

[英]Reverse String function in C without library functions

This is my task: 这是我的任务:

Realize function that reverses null terminated string. 实现反转空终止字符串的函数。 The prototype of the function is void Reverse(char *ptr); 该函数的原型为void Reverse(char *ptr); . Do not use standard library functions. 不要使用标准库函数。

This is my code for now: 这是我现在的代码:

void Reverse(char *ptr) {
    char *newString;
    char ch = *ptr;
    unsigned int size = 0;

    for (int i = 1; ch != '\0'; i++) {
        ch = *(ptr + i);
        size++;
    }

    newString = (char*)malloc(size);

    for (int left = 0, right = size - 1; left < size; left++, right--) {
        *(newString + left) = *(ptr + right);
    }

    printf("%s", newString);
    printf("\n");
}

It reverses the string and saves it in the newString 它反转字符串并将其保存在newString中

My first problem is that when I print the newString to see if the functions works the string is reversed, but after it there are some symbols. 我的第一个问题是,当我打印newString以查看函数是否起作用时,该字符串被反转了,但是在它后面有一些符号。

For example: If I have char *str = "hello"; 例如:如果我有char *str = "hello"; and Reverse(str); Reverse(str); in the main method the result of printf("%s", newString) will be olleh**** . main方法中, printf("%s", newString)将为olleh****

But if change the newString = (char*)malloc(size); 但是如果更改newString = (char*)malloc(size); to newString = (char*)malloc(1); newString = (char*)malloc(1); it works fine. 它工作正常。

My second problem is that I don't know how to save the newString into the given one. 我的第二个问题是我不知道如何将newString保存到给定的字符串中。 I am using a new String because the given one can't be changed. 我使用的是新字符串,因为给定的字符串无法更改。

For starters it is better to declare the function like 对于初学者,最好将函数声明为

char * Reverse( char *ptr );
^^^^^^

because standard C string functions usually return pointers to destination strings. 因为标准的C字符串函数通常返回指向目标字符串的指针。

The function should reverse the original string. 该函数应反转原始字符串。 It may not create a dynamic string because the caller of the function will be unable to free it provided that the function has return type void. 它可能不会创建动态字符串,因为如果函数的返回类型为void,则函数的调用者将无法释放它。

The function can look as it is shown in the following demonstrative program. 该函数可以看起来像下面的演示程序中所示。

#include <stdio.h>

char * Reverse( char *ptr )
{
    char *first = ptr, *last = ptr;

    while ( *last ) ++last;

    if ( first < last )
    {
        for ( ; first < --last; ++first  )
        {
            char c = *first;
            *first = *last;
            *last  = c;
        }
    }

    return ptr;
}

int main( void ) 
{
    char s[] = "Hello World!";

    puts( s );
    puts( Reverse( s ) );

    return 0;
}

Its output is 它的输出是

Hello World!
!dlroW olleH

Take into account that you may not call the function like 考虑到您可能不会像

puts( Reverse( "Hello World!" ) );

because string literals are immutable in C. 因为字符串文字在C中是不可变的。

If you are going to declare the function like 如果您要声明类似

void Reverse( char *ptr );

then just remove the return statement in the shown function. 然后只需删除所示函数中的return语句即可。 For example 例如

#include <stdio.h>

void Reverse( char *ptr )
{
    char *first = ptr, *last = ptr;

    while ( *last ) ++last;

    if ( first < last )
    {
        for ( ; first < --last; ++first  )
        {
            char c = *first;
            *first = *last;
            *last  = c;
        }
    }
}

int main( void ) 
{
    char s[] = "Hello World!";

    puts( s );
    Reverse( s )
    puts( s );

    return 0;
}

If to use your approach with indices then the function can look like 如果对索引使用您的方法,则该函数可能看起来像

#include <stdio.h>

void Reverse( char *ptr ) 
{
    size_t size = 0;

    while ( *( ptr + size ) ) ++size;

    if ( size != 0 )
    {
        for ( size_t left = 0, right = size - 1; left < right; left++, right-- ) 
        {
            char c     = ptr[left];    // or char c = *( ptr + left ); and so on
            ptr[left]  = ptr[right];
            ptr[right] = c;
        }           
    }
}

int main( void ) 
{
    char s[] = "Hello World!";

    puts( s );
    Reverse( s );
    puts( s );

    return 0;
}

In your loop to get the size, you're not counting the null terminator. 在获取大小的循环中,您没有计算空终止符。 So your newString is missing the null terminator as well. 因此,您的newString也缺少空终止符。 make sure to do newString = malloc(size + 1); 确保做newString = malloc(size + 1); , and to place the null terminator onto the end of newString . ,并将空终止符放在newString的末尾。

You have several problems in your code: 您的代码中有几个问题:

  • you do not allocate enough space for the resulting string, you must allocate size+1 bytes and set the \\0 terminator at the end of the string. 您没有为结果字符串分配足够的空间,必须分配size+1个字节并在字符串末尾设置\\0终止符。
  • you only copy half the characters from ptr to newString . 您只需将一半字符从ptr复制到newString
  • you are not even supposed to allocate memory, since you cannot call any library functions. 您甚至不应该分配内存,因为您不能调用任何库函数。 You should instead reverse the string in place. 相反,您应该将字符串反转就位。
  • Your test fails because modifying a string literal invokes undefined behavior. 测试失败,因为修改字符串文字会调用未定义的行为。 You should pass an initialized array as shown below. 您应该传递一个初始化的数组,如下所示。

Here is an improved version: 这是一个改进的版本:

#include <stdio.h>

void Reverse(char *ptr) {
    unsigned int left, right;

    for (right = 0; *(ptr + right) != '\0'; right++) {
         continue;
    }

    for (left = 0; left < right; left++, right--) {
        char ch = ptr[left];
        ptr[left] = ptr[right - 1];
        ptr[right - 1] = ch;
    }
}

int main(void) {
    char buf[] = "Hello world";
    Reverse(buf);
    printf("%s\n", buf);
    return 0;
}

It should print dlrow olleH . 它应该打印dlrow olleH

Simple string reverse function without string.h library functions : 没有string.h库函数的简单字符串反向函数:

#include <stdio.h>
void reverse(char *str, int n);
int main()
{
    char str[100];
    int n;
    printf("Enter a string\n");
    scanf("%s",&str);
    for( n = 0; str[n] != '\0'; n++)
    {

    }
    reverse(str,n);
    puts(str);
    return 0;
}
void reverse(char *str,int n)
{
    printf("Length = %d\n",n);
    printf("Reversed :\n");
    int i;
    char ch;
    for(i = 0; i<n/2; i++)
    {
        ch = str[i];
        str[i] = str[n-i-1];
        str[n-i-1] = ch;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM