C 中的字符串反转
我知道这个问题已被问过数千次,但我只是在代码中找不到错误。有人可以指出我做错了什么吗?
#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);
}
I know this has been asked thousands of times but I just can't find the error in my code. Could someone kindly point out what I'm doing wrong?
#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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
最终,将其反转到位会更清晰,如下所示:
您的解决方案本质上是该解决方案在语义上的更大版本。了解指针和数组之间的区别。该标准明确指出此类操作(修改字符串文字的内容)的行为是未定义的。您还应该看到爱斯基摩人的此摘录:
当您初始化角色时带有字符串常量的数组:
您最终得到一个包含字符串的数组,并且您可以将数组的内容修改为您想要的内容:
但是,可以在代码中的其他位置使用字符串常量(正式术语是字符串文字) 。由于它们是数组,因此当它们在表达式中使用时,编译器会像往常一样生成指向其第一个元素的指针。也就是说,如果您说
这几乎就像您说的那样
,名为“internal_string_1”和“internal_string_2”的数组应该表明这样一个事实:每次您在代码中使用字符串常量时,编译器实际上都会生成一些临时数组。然而,微妙的事实是字符串常量“后面”的数组不一定是可修改的。特别地,编译器可以将它们存储在只读存储器中。因此,如果您编写
程序可能会崩溃,因为它可能会尝试将值(在本例中为字符“J”)存储到不可写内存中。
其寓意是,无论何时构建或修改字符串,都必须确保构建或修改字符串的内存是可写的。该内存应该是您分配的数组,或者是您通过我们将在下一章中看到的技术动态分配的一些内存。确保程序的任何部分都不会尝试修改实际上是编译器响应字符串常量之一而为您生成的未命名、不可写数组之一的字符串。 (唯一的例外是数组初始化,因为如果您写入这样的数组,您正在写入该数组,而不是写入用于初始化该数组的字符串文字。)”
Ultimately, it would be cleaner to reverse it in place, like so:
Your solution is essentially a semantically larger version of this one. Understand the difference between a pointer and an array. The standard explicitly states that the behviour of such an operation (modification of the contents of a string literal) is undefined. You should also see this excerpt from eskimo:
When you initialize a character array with a string constant:
you end up with an array containing the string, and you can modify the array's contents to your heart's content:
However, it's possible to use string constants (the formal term is string literals) at other places in your code. Since they're arrays, the compiler generates pointers to their first elements when they're used in expressions, as usual. That is, if you say
it's almost as if you'd said
Here, the arrays named internal_string_1 and internal_string_2 are supposed to suggest the fact that the compiler is actually generating little temporary arrays every time you use a string constant in your code. However, the subtle fact is that the arrays which are ``behind'' the string constants are not necessarily modifiable. In particular, the compiler may store them in read-only-memory. Therefore, if you write
your program may crash, because it may try to store a value (in this case, the character 'J') into nonwritable memory.
The moral is that whenever you're building or modifying strings, you have to make sure that the memory you're building or modifying them in is writable. That memory should either be an array you've allocated, or some memory which you've dynamically allocated by the techniques which we'll see in the next chapter. Make sure that no part of your program will ever try to modify a string which is actually one of the unnamed, unwritable arrays which the compiler generated for you in response to one of your string constants. (The only exception is array initialization, because if you write to such an array, you're writing to the array, not to the string literal which you used to initialize the array.) "
问题是
somestring 指向字符串“hello”。 C++ 标准不保证这一点,但在大多数机器上,这将是只读数据,因此不允许您修改它。
改为这样声明
the problem is here
somestring points to the string literal "hello". the C++ standard doesn't gurantee this, but on most machines, this will be read-only data, so you won't be allowed to modify it.
declare it this way instead
您通过尝试修改潜在的只读内存区域来调用未定义行为(字符串文字隐式为 const - 可以读取它们,但不能写入它们)。创建一个新字符串并返回它,或者传递一个足够大的缓冲区并将反转的字符串写入其中。
You are invoking Undefined Behavior by trying to modify a potentially read-only memory area (string literals are implicitly
const
-- it's ok to read them but not to write them). Create a new string and return it, or pass a large enough buffer and write the reversed string to it.您可以使用以下代码
You can use the following code
我认为调用 strrev() 是不可能的吗?
I take it calling strrev() is out of the question?
你的逻辑看起来是正确的。处理
char[]
比使用指针更干净。Your logic seems correct. Instead of using pointers, it is cleaner to deal with
char[]
.