如何在 C 中编辑 char* 字符串的值?
How to edit values of a char* string in C?
我刚开始学习 C,我不太确定如何"correctly" 访问和编辑字符指针的值。
例如:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* text = malloc(20);
char* othertext = "Teststring";
do
{
*text++ = *othertext++;
} while (*othertext != '[=10=]');
printf("%s\n", text + 3);
free(text);
return 0;
}
首先,为什么do-while函数不起作用? "othertext" 的内容不会复制到 "text" 指针。此外,在执行 free(text) 时程序会崩溃!
我们知道如果我们添加第二个指针,这段代码就可以工作:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* text = malloc(20);
char* othertext = "Teststring";
char *ptr1 = text;
char *ptr2 = othertext;
do
{
*ptr1++ = *ptr2++;
} while (*ptr2 != '[=11=]');
printf("%s\n", text + 3);
free(text);
return 0;
}
但是两个指针的地址基本相同!它们在调试器中具有相同的值,那么第二个指针有何不同?
最后一点:我们不允许使用 string.h。我们确实知道数组和指针之间存在细微差别。但是我们需要具体了解char*是如何工作的!
您应该将 malloc()
返回的指针传递给 free()
(相同的地址)。您正在传递递增的指针,即 text
指针现在没有 malloc()
返回的指针地址,而是 text
的最后一个元素的地址,使用另一个指针复制数据,或者更好的索引
size_t i;
for (i = 0 ; othertext[i] != '[=10=]' ; ++i)
text[i] = othertext[i];
text[i] = '[=10=]';
你说
But both pointers have basically the same address!
这不是真的,试试这个
printf("%p -- %p\n", (void *) text, (void *) ptr1);
您在循环中修改了 text
指针的值,这样在结束时它不指向您分配的内存区域的开头;这就是(部分)您看不到文本的原因,也是 free
崩溃的原因。
您需要保留原始指针值(您在第二个代码段中这样做)。
您实际上是在更改 text
指向的地址。
考虑一个非常简单的内存,其中 text
指向地址 5
,othertext
指向地址 42
,其中 T
的 TestString
已放置。
您现在将在地址 42
找到的字符复制到地址 5
,这样地址 5
也包含一个 T
。但是,您现在也增加了 text
指向的地址。换句话说,text
现在指向地址 6
。您还增加 othertext
现在指向地址 43
.
在下一轮中,您将在地址 43
处找到的 e
复制到地址 6
并再次递增两者。这一切都很好。
但是在您完成复制后 text
将指向 5 + 10 = 15
。但是在地址 15
上你不能打印任何东西,也不能删除那里的东西。
在你的第二段代码中没有问题,因为 text
一直指向地址 5
.
在赋值行之后的循环内执行此 printf。我想你会明白为什么它不起作用 ;)
printf("%s\n", text);
我刚开始学习 C,我不太确定如何"correctly" 访问和编辑字符指针的值。
例如:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* text = malloc(20);
char* othertext = "Teststring";
do
{
*text++ = *othertext++;
} while (*othertext != '[=10=]');
printf("%s\n", text + 3);
free(text);
return 0;
}
首先,为什么do-while函数不起作用? "othertext" 的内容不会复制到 "text" 指针。此外,在执行 free(text) 时程序会崩溃!
我们知道如果我们添加第二个指针,这段代码就可以工作:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* text = malloc(20);
char* othertext = "Teststring";
char *ptr1 = text;
char *ptr2 = othertext;
do
{
*ptr1++ = *ptr2++;
} while (*ptr2 != '[=11=]');
printf("%s\n", text + 3);
free(text);
return 0;
}
但是两个指针的地址基本相同!它们在调试器中具有相同的值,那么第二个指针有何不同?
最后一点:我们不允许使用 string.h。我们确实知道数组和指针之间存在细微差别。但是我们需要具体了解char*是如何工作的!
您应该将 malloc()
返回的指针传递给 free()
(相同的地址)。您正在传递递增的指针,即 text
指针现在没有 malloc()
返回的指针地址,而是 text
的最后一个元素的地址,使用另一个指针复制数据,或者更好的索引
size_t i;
for (i = 0 ; othertext[i] != '[=10=]' ; ++i)
text[i] = othertext[i];
text[i] = '[=10=]';
你说
But both pointers have basically the same address!
这不是真的,试试这个
printf("%p -- %p\n", (void *) text, (void *) ptr1);
您在循环中修改了 text
指针的值,这样在结束时它不指向您分配的内存区域的开头;这就是(部分)您看不到文本的原因,也是 free
崩溃的原因。
您需要保留原始指针值(您在第二个代码段中这样做)。
您实际上是在更改 text
指向的地址。
考虑一个非常简单的内存,其中 text
指向地址 5
,othertext
指向地址 42
,其中 T
的 TestString
已放置。
您现在将在地址 42
找到的字符复制到地址 5
,这样地址 5
也包含一个 T
。但是,您现在也增加了 text
指向的地址。换句话说,text
现在指向地址 6
。您还增加 othertext
现在指向地址 43
.
在下一轮中,您将在地址 43
处找到的 e
复制到地址 6
并再次递增两者。这一切都很好。
但是在您完成复制后 text
将指向 5 + 10 = 15
。但是在地址 15
上你不能打印任何东西,也不能删除那里的东西。
在你的第二段代码中没有问题,因为 text
一直指向地址 5
.
在赋值行之后的循环内执行此 printf。我想你会明白为什么它不起作用 ;)
printf("%s\n", text);