10

我知道这已经被问了数千次,但我只是在我的代码中找不到错误。有人可以指出我做错了什么吗?

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

void reverseString(char *myString){
  char temp;
  int len = strlen(myString);

  char *left = myString;
  //  char *right = &myString[len-1];                                                                                        
  char *right = myString + strlen(myString) - 1;

  while(left < right){
    temp = *left;
    *left = *right; // this line seems to be causing a segfault                                                              
    *right = temp;
    left++;
    right--;
  }
}

int main(void){
  char *somestring = "hello";
  printf("%s\n", somestring);
  reverseString(somestring);

  printf("%s", somestring);

}
4

6 回答 6

13

最终,将其反转到位会更清洁,如下所示:

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

void
reverse(char *s)
{
    int a, b, c;
    for (b = 0, c = strlen(s) - 1; b < c; b++, c--) { 
        a = s[b]; 
        s[b] = s[c]; 
        s[c] = a; 
    }

    return; 
}

int main(void)
{
    char string[] = "hello";
    printf("%s\n", string);
    reverse(string);
    printf("%s\n", string);

    return 0;
}

您的解决方案本质上是这个解决方案的语义更大版本。了解指针和数组之间的区别。该标准明确指出这种操作的行为(修改字符串文字的内容)是未定义的。您还应该看到爱斯基摩人的这段摘录:

当您使用字符串常量初始化字符数组时:

char string[] = "Hello, world!";

你最终得到一个包含字符串的数组,你可以将数组的内容修改为你心中的内容:

string[0] = 'J';

但是,可以在代码的其他位置使用字符串常量(正式术语是字符串文字)。由于它们是数组,因此编译器在表达式中使用它们时会生成指向它们的第一个元素的指针,就像往常一样。也就是说,如果你说

char *p1 = "Hello";
int len = strlen("world");

就像你说的

char internal_string_1[] = "Hello";
char internal_string_2[] = "world";
char *p1 = &internal_string_1[0];
int len = strlen(&internal_string_2[0]);

在这里,名为 internal_string_1 和 internal_string_2 的数组应该表明编译器实际上每次在代码中使用字符串常量时都会生成少量临时数组。然而,微妙的事实是,字符串常量“后面”的数组不一定是可修改的。特别是,编译器可以将它们存储在只读存储器中。因此,如果你写

char *p3 = "Hello, world!";
p3[0] = 'J';

您的程序可能会崩溃,因为它可能会尝试将一个值(在本例中为字符“J”)存储到不可写内存中。

寓意是,每当您构建或修改字符串时,您必须确保您正在构建或修改它们的内存是可写的。该内存应该是您分配的数组,或者是您通过我们将在下一章中看到的技术动态分配的内存。确保程序的任何部分都不会尝试修改实际上是编译器为响应您的字符串常量之一而为您生成的未命名、不可写数组之一的字符串。(唯一的例外是数组初始化,因为如果您写入这样的数组,您写入的是数组,而不是用于初始化数组的字符串字面量。)“

于 2010-02-27T00:19:21.737 回答
12

问题就在这里

char *somestring = "hello";

somestring 指向字符串文字“hello”。C++ 标准不保证这一点,但在大多数机器上,这将是只读数据,因此您将无法修改它。

改为这样声明

char somestring[] = "hello";
于 2010-02-26T23:54:50.553 回答
5

您正在通过尝试修改潜在的只读内存区域来调用未定义的行为(字符串文字是隐式const的——可以读取它们但不能写入它们)。创建一个新字符串并将其返回,或者传递一个足够大的缓冲区并将反转的字符串写入其中。

于 2010-02-26T23:54:01.727 回答
0

您可以使用以下代码

#include<stdio.h>
#include<string.h>
#include<malloc.h>
char * reverse(char*);

int main()
{
        char* string = "hello";
        printf("The reverse string is : %s", reverse(string));
        return 0;
}

char * reverse(char* string)
{

   int var=strlen(string)-1;
     int i,k;
     char *array;
     array=malloc(100);
     for(i=var,k=0;i>=0;i--)
    {
           array[k]=string[i];
            k++;
   }
  return array;
}
于 2010-03-01T09:37:13.297 回答
0

我认为调用 strrev() 是不可能的?

于 2010-03-01T09:47:54.043 回答
-1

你的逻辑似乎是正确的。与其使用指针,不如处理char[].

于 2010-02-27T00:00:57.873 回答