【问题标题】:Reverse String function in C without library functions没有库函数的C中的反向字符串函数
【发布时间】:2016-07-15 12:21:02
【问题描述】:

这是我的任务:

实现反转空终止字符串的功能。该函数的原型是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 以查看函数是否正常工作时,字符串是反转的,但在它之后有一些符号。

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

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

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

【问题讨论】:

  • 空终止......
  • 是返回一个反向字符串,还是简单地反向打印?
  • malloc 不算标准库函数?
  • 彼得我也无法理解,如果我必须打印或退回它。
  • 请考虑您可以通过连续交换就地反转字符串。例如,字符串"james"。如果你交换第一个和最后一个字符,你会得到"samej"。如果你交换第二个和倒数第二个,你会得到"semaj",这是反转的字符串。我将把编写循环的任务留给你。

标签: c string algorithm pointers reverse


【解决方案1】:

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

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

【讨论】:

  • 一些标准的 C 字符串函数返回指针。并非所有人都这样做。
  • @Peter 哪些标准 C 字符串函数的返回类型为 void?
  • 我无法更改原型。
  • @StanislavFotev 没问题。只需删除函数中的 return 语句,正如我在帖子中已经指出的那样。:) 在这种情况下,演示程序将具有像 puts(s); 这样的语句。反向(s);放(小号);
  • @StanislavFotev 完全没有。我们初学者应该互相帮助。:)
【解决方案2】:

在获取大小的循环中,您没有计算空终止符。因此,您的 newString 也缺少空终止符。确保执行newString = malloc(size + 1);,并将空终止符放在newString 的末尾。

【讨论】:

  • 并记得让你的循环终止案例离开
  • 感谢您的回答我解决了我的第一个问题,但我不知道如何在不更改原型的情况下返回字符串。
  • 在这种情况下,他们可能希望反转原始字符串输入,因此请使用 Vlad 的答案并保持原型不变并删除其末尾的 return
【解决方案3】:

您的代码中有几个问题:

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

这是一个改进的版本:

#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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 2014-03-30
      • 2019-07-24
      • 2018-05-14
      相关资源
      最近更新 更多