我遇到了一个将数组内容(来自用户的输入)转换为预先声明的速记的赋值。
我希望它像strcpy一样简单(“和”,“+”); 将字符串中的'和'更改为'+'符号。
不幸的是,无论我如何构建功能;我得到了一个弃用的转换警告(变量循环和直接应用程序,尝试过)。
旁注;这是基于赋值的,所以我的字符串快捷方式受到严格限制,并且没有指针(我已经看到使用它们清除故障的几个版本)。
我不是在找人做我的作业;只是指导如何在不创建dep的情况下应用strcpy。警告。也许我根本不应该使用strcpy?
答案 0 :(得分:2)
strcpy
将第二个字符串的内容复制到第一个字符串的内存中。由于您将字符串文字复制到字符串文字中,因此无法执行此操作(您无法写入字符串文字),因此会抱怨。
相反,您需要构建自己的搜索和替换系统。您可以使用strstr()
搜索字符串中的子字符串,并将内存中的指针返回到找到的字符串的开头(如果已找到)。
我们取样本字符串Jack and Jill went up the hill
。
char *andloc = strstr(buffer, " and ");
这将返回字符串开头的地址(比如0x100
)加上单词&#34的偏移量;和" (包括空格)在其中(0x100 + 4
),即0x104
。
然后,如果找到,您可以将其替换为&
符号。但是,您不能使用strcpy
,因为它会终止字符串。相反,您可以手动设置字节,或使用memcpy:
if (andloc != NULL) { // it's been found
andloc[1] = '&';
andloc[2] = ' ';
}
或:
if (andloc != NULL) { // it's been found
memcpy(andloc, " & ", 3);
}
这将导致Jack & d Jill went up the hill
。我们还没到那里。接下来,你必须将所有东西都洗干净以覆盖" d"来自旧的"和"。为此,您认为现在可以使用strcpy
或memcpy
,但这是不可能的 - 字符串(源和目标)重叠,并且两者都是特定状态的手册页字符串不得重叠并改为使用memmove
。
所以你可以在" d"之后移动字符串的内容。之后"& "代替:
memmove(andloc + 3, andloc + 5, strlen(andloc + 5) + 1);
将数字添加到类似的字符串会添加到指针的地址。因此,我们正在考虑在旧的"和"的字符串中进一步复制5个字符的数据。位于从旧"和#34;开头的3个字符开始的空间中地点。要复制的数量是从"和"开头的5个字符开始的字符串的长度。 location加一,所以它会复制字符串末尾的NULL字符。
另一种手动方式是迭代每个字符,直到找到字符串的结尾:
char *to = andloc + 3;
char *from = andloc + 5;
while (*from) { // Until the end of the string
*to = *from; // Copy one character
to++; // Move to the ...
from++; // ... next character pair
}
*to = 0; // Add the end of string marker.
所以现在字符串内存包含:
Jack & Jill went up the hill\0l\0
\0
是字符串标记的结尾,因此实际字符串"内容"仅在第一个\0
时出现,l\0
现在被忽略。
请注意,这仅适用于使用较小的部件替换部件时。如果你用更大的东西替换它,所以字符串的大小增加,你将被迫使用memmove
,它首先将内容复制到暂存器,并确保你的缓冲区有足够的空间来存储完成字符串(这种事情通常是"缓冲区溢出的重要来源"这是一个安全问题,也是系统被黑客入侵的最大原因之一)。此外,你必须向后做整个事情 - 首先移动字符串的后半部分以腾出空间,然后修改两半之间的间隙。