【问题标题】:Reverse string in C [duplicate]C中的反向字符串[重复]
【发布时间】: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,尤其是“描述”和“错误”部分,如果有人教你使用它,请尝试其他学习材料。
  • 来自这个垃圾网站coderbyte.com/solution/First%20Reverse
  • 除此之外我的代码是否正确?

标签: c string reverse


【解决方案1】:
  1. 只运行到字符串中间
  2. 将被覆盖的字符保留在循环中的某个 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.

这里有三个问题:

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

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

  3. (次要)(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

【讨论】:

  • 谢谢!非常感谢您的回答,它向我展示了解决问题的另一种方法!
  • 此代码泄漏内存。
猜你喜欢
  • 1970-01-01
  • 2015-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多