C中的反向字符串[重复]

Posted

技术标签:

【中文标题】C中的反向字符串[重复]【英文标题】:Reverse string in C [duplicate] 【发布时间】:2019-12-09 19:52:22 【问题描述】:

我只想通过切换字符串中每个索引的位置来反转字符串顺序。

#include <stdio.h>
#include <string.h>

void FirstReverse(char str[])   
  int a = strlen(str);

  for(int i=0; i<strlen(str) ;i++)
    str[i] = str[a-1];
    a-=1;
  


int main(void) 
  // keep this function call here
  FirstReverse(gets(stdin));
  return 0;    

错误:“信号:分段错误(核心转储)”

【问题讨论】:

gets(stdin) 真的??? 打开编译器警告并注意它们。 恐怕这是gets的错误用法,而不是由您的算法引起的。首先,它并不意味着将stdin 作为一个论点。我建议你阅读its documentation,尤其是“描述”和“错误”部分,如果有人教你使用它,请尝试其他学习材料。 ***.com/questions/55269252/… 来自这个垃圾网站coderbyte.com/solution/First%20Reverse 除此之外我的代码是否正确? 【参考方案1】:
    只运行到字符串中间 将被覆盖的字符保留在循环中的某个 var 中

#include<stdio.h>

#include <stdlib.h>

#include <string.h>

void FirstReverse(char str[]) 

    int a = strlen(str);

    for (int i = 0; i <= a; ++i, --a) 
        char c = str[i];
        str[i] = str[a - 1];
        str[a - 1] = c;
    


int main(void) 
    // keep this function call here

    char s[100] =  0 ;
    scanf("%s",s);

    FirstReverse(s);

    printf("%s",s);

    return 0;

【讨论】:

您的代码读取并反转一个单词。与问题代码相比,您至少应该提及这种差异。 感谢您向我展示了解决问题的另一种方法!非常感谢!【参考方案2】:

您的代码中有多个错误。显而易见的是 gets 使用错误(老实说,that it is used at all)并且它不会以任何方式输出结果。但是,让我们应用一些对您的逻辑进行最小更改的快速修复:

#include <stdio.h>
#include <string.h>

void FirstReverse(char str[]) 
  int a = strlen(str);

  for(int i=0; i<strlen(str) ;i++)
    str[i] = str[a-1];
    a-=1;
  


int main(void) 
  char string[100];  // This is going to be our working field where the changes happen
  fgets(string, 100, stdin);  // read a line of up to 100 characters into "string"
  FirstReverse(string);  // do the work (this could be chained, like it was originally)
  puts(string);  // output the result
  return 0;

现在它编译并执行没有失败但结果是错误的:

在:我最喜欢的字符串

输出:gnirts ette 字符串

出了什么问题?让我们一步一步来看看会发生什么:

i                  a
↓                  ↓
My favourite string
(program writes the last character [see point 3 below] in place of `M`)

 ↓                ↓
 y favourite string
(program writes `g` in place of `y`)

  ↓              ↓
 g favourite string
(program writes `n` in place of the space)

   ↓            ↓
 gnfavourite string
(program writes `i` in place of `f`)

etc.
         ia
         ↓↓
 gnirts eite string
(program writes `t` in place of `i`)

         ai
         ↓↓
 gnirts ette string
(program writes `t` in place of `t`)

        a  i
        ↓  ↓
 gnirts ette string
(program writes `e` in place of `e`)
etc.

这里有三个问题:

    通过将一个字符从头重写为另一个字符,您并没有进行交换。您只是从头到尾复制数据(但肯定是按相反的顺序)。原件丢失了。

    您实际上是通过了两次,因为当i 达到间隔的一半时,a 不断减少并且它们交叉。现在i 仍然需要完成循环,a 继续向您已经到达的字符串的开头。如果你真的确实交换过,你会用 2 交换 1,然后再用 1 交换 2,导致原来的不变!

    (次要)(f)gets 返回的字符串以换行符结尾,因此它成为结果的开始。可能不是您想要的,但可以在将字符串输入函数之前轻松解决。

您需要处理每一个问题,其他答案现在包含一些建议。但是我认为运行你的代码并尝试“像机器一样思考”来解释为什么计算机会误解你的意图是有启发性的。如果您通过在临时变量中复制一个字母来交换字母,然后重写str[i],然后从临时变量中写回str[a-1],并在ia 相互交叉之前停止,您可以自己看到'会照顾 1 和 2。

【讨论】:

“gets用错了”,嗯,没有正确的使用方法…… @hyde 好吧,我在发布答案之前在我的评论中写了这个。但是,是的,重复一遍是个好主意。 谢谢你的回答,对我的学习很有帮助!【参考方案3】:

简单的方法:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char * reverse(char *str)

    size_t size = strlen(str);
    char *res = malloc(size * sizeof(char));
    for(size_t i=0; i<size; i++) 
        res[i] = str[size-i-1];
    
    return res;


int main(void)

    printf("%s\n",reverse("Hello World"));
    return 0;

输出:dlroW olleH

不要切换每个char,只需创建一个新字符串,在其中复制最后一个char,然后是last-1,依此类推。如果字符串的长度不均匀('\0' 放在一边),您还可以防止自己切换相同的 char

【讨论】:

谢谢!非常感谢您的回答,它向我展示了解决问题的另一种方法! 此代码泄漏内存。

以上是关于C中的反向字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章

没有反向功能的反向字符串[重复]

使用交换和递归在 C 和 C++ 中的字符串反向性能

c_cpp 151.字符串中的反向词 - DifficultyMedium - 2018.9.5

正则表达式反向引用乘法[重复]

将参数字符串中的字符反向排列,不是逆序打印。用递归实现

枚举反向查找[重复]