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

时间:2016-07-15 12:21:02

标签: c string algorithm pointers reverse

这是我的任务:

实现反转空终止字符串的函数。函数的原型是void Reverse(char *ptr);。不要使用标准库函数。

这是我现在的代码:

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

它会反转字符串并将其保存在newString

我的第一个问题是,当我打印newString以查看函数是否有效时,字符串是反转的,但在它之后有一些符号。

例如: 如果我在char *str = "hello";方法中有Reverse(str);main printf("%s", newString)的结果为olleh****

但是,如果改变了 newString = (char*)malloc(size);newString = (char*)malloc(1);它工作正常。

我的第二个问题是我不知道如何将newString保存到给定的中。我正在使用一个新的String,因为无法更改给定的字符串。

4 个答案:

答案 0 :(得分:4)

对于初学者来说,最好将声明声明为

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

因为标准C字符串函数通常会返回指向目标字符串的指针。

该函数应该反转原始字符串。它可能不会创建动态字符串,因为如果函数的返回类型为void,函数的调用者将无法释放它。

该功能可以如以下说明性程序所示。

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

它的输出是

Hello World!
!dlroW olleH

考虑到你可能不会像

那样调用这个功能
puts( Reverse( "Hello World!" ) );

因为字符串文字在C中是不可变的。

如果你要声明像

这样的功能
void Reverse( char *ptr );

然后只删除所示函数中的return语句。例如

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

如果要使用带索引的方法,那么函数可能看起来像

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

答案 1 :(得分:1)

在你的循环中获取大小,你不计算null终止符。所以你的newString也缺少空终止符。确保执行newString = malloc(size + 1);,并将空终止符放在newString的末尾。

答案 2 :(得分:1)

您的代码中有几个问题:

  • 您没有为结果字符串分配足够的空间,您必须分配size+1字节并在字符串末尾设置\0终止符。
  • 您只能将ptr中的一半字符复制到newString
  • 你甚至不应该分配内存,因为你不能调用任何库函数。你应该反过来反转字符串。
  • 您的测试失败,因为修改字符串文字会调用未定义的行为。您应该传递一个初始化的数组,如下所示。

以下是改进版本:

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

应打印dlrow olleH

答案 3 :(得分:0)

没有toggle(document.getElementsByTagName("nav")[0]); 库函数的简单字符串反转函数:

string.h