C++ 阵列转换制导
我被一个将数组内容(来自用户的输入)转换为预先声明的速记的赋值所困扰 我希望它像strcpy(“and“,“+”)一样简单; 将字符串中的“and”改为“+”号 不幸的是,无论我如何构造函数;我收到一条不推荐使用的转换警告(尝试了变量循环和直接应用程序) 旁注;这是基于赋值的,因此我的字符串快捷方式受到严格限制,并且没有指针(我见过几个版本使用它们清除错误)C++ 阵列转换制导,c++,arrays,C++,Arrays,我被一个将数组内容(来自用户的输入)转换为预先声明的速记的赋值所困扰 我希望它像strcpy(“and“,“+”)一样简单; 将字符串中的“and”改为“+”号 不幸的是,无论我如何构造函数;我收到一条不推荐使用的转换警告(尝试了变量循环和直接应用程序) 旁注;这是基于赋值的,因此我的字符串快捷方式受到严格限制,并且没有指针(我见过几个版本使用它们清除错误) 我不是在找人做作业;只是关于如何在不创建副警告的情况下应用strcpy的指导。也许我根本不应该使用strcpy?strcpy将第二个字符串
我不是在找人做作业;只是关于如何在不创建副警告的情况下应用strcpy的指导。也许我根本不应该使用strcpy?
strcpy
将第二个字符串的内容复制到第一个字符串的内存中。由于您要将字符串文字复制到字符串文字,所以它无法执行此操作(您无法写入字符串文字),因此它会抱怨
相反,您需要构建自己的搜索和替换系统。您可以使用strstrstr()
搜索字符串中的子字符串,它会将内存中的指针返回到找到的字符串的开头(如果找到了)
让我们以示例字符串为例,杰克和吉尔上山了
char *andloc = strstr(buffer, " and ");
这将返回字符串开头的地址(比如0x100
)加上其中单词“and”(包括空格)的偏移量(0x100+4
),即0x104
然后,如果找到,可以将其替换为&
符号。但是,您不能使用strcpy,因为它将终止字符串。相反,您可以手动设置字节,或使用memcpy:
if (andloc != NULL) { // it's been found
andloc[1] = '&';
andloc[2] = ' ';
}
或:
这将导致杰克和迪吉尔上山。我们还没有完全做到。下一步,你必须把所有的东西洗牌下来,以覆盖旧的“and”中的“d”。为此,您可能认为现在可以使用strcpy
或memcpy
,但这是不可能的-字符串(源和目标)重叠,并且这两个字符串的手册页都明确指出,字符串不能重叠,而是使用memmove
因此,您可以将“d”之后的字符串内容移动到“&”之后:
memmove(andloc + 3, andloc + 5, strlen(andloc + 5) + 1);
向字符串中添加一个数字,这样会增加指针的地址。因此,我们正在考虑将数据从字符串中的5个字符进一步复制到一个空间中,该空间从旧的“and”位置开始,从3个字符开始。要复制的数量是从“and”位置开始的5个字符加上1的字符串长度,因此它复制字符串末尾的空字符
另一种手动方法是遍历每个字符,直到找到字符串的结尾:
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
,它首先将内容复制到草稿行,并确保您的缓冲区中有足够的空间来存储完成的字符串(这类事情通常是“缓冲区溢出”的一大根源)这是一个令人头疼的安全问题,也是系统被黑客攻击的最大原因之一)。此外,您还必须将整个过程向后移动—首先移动字符串的后半部以腾出空间,然后修改两半之间的间隙。strcpy
将第二个字符串的内容复制到第一个字符串的内存中。由于您要将字符串文字复制到字符串文字,所以它无法执行此操作(您无法写入字符串文字),因此它会抱怨
相反,您需要构建自己的搜索和替换系统。您可以使用strstrstr()
搜索字符串中的子字符串,它会将内存中的指针返回到找到的字符串的开头(如果找到了)
让我们以示例字符串为例,杰克和吉尔上山了
char *andloc = strstr(buffer, " and ");
这将返回字符串开头的地址(比如0x100
)加上其中单词“and”(包括空格)的偏移量(0x100+4
),即0x104
然后,如果找到,可以将其替换为&
符号。但是,您不能使用strcpy,因为它将终止字符串。相反,您可以手动设置字节,或使用memcpy:
if (andloc != NULL) { // it's been found
andloc[1] = '&';
andloc[2] = ' ';
}
或:
这将导致杰克和迪吉尔上山。我们还没有完全做到。下一步,你必须把所有的东西洗牌下来,以覆盖旧的“and”中的“d”。为此,您可能认为现在可以使用strcpy
或memcpy
,但这是不可能的-字符串(源和目标)重叠,并且这两个字符串的手册页都明确指出,字符串不能重叠,而是使用memmove
因此,您可以将“d”之后的字符串内容移动到“&”之后:
memmove(andloc + 3, andloc + 5, strlen(andloc + 5) + 1);
向字符串中添加一个数字,这样会增加指针的地址。因此,我们正在考虑将数据从字符串中的5个字符进一步复制到一个空间中,该空间从旧的“and”位置开始,从3个字符开始。要复制的数量是从“and”位置开始的5个字符加上1的字符串长度,因此它复制字符串末尾的空字符
另一种手动方法是遍历每个字符,直到找到字符串的结尾:
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
是字符串结束标记,因此实际字符串“内容”仅在