有没有简单的方法来复制C字符串?
我有const char *stringA
,我希望char *stringB
获取值(请注意stringB
不是const
)。我尝试了stringB=(char*) stringA
,但这使stringB
仍然指向相同的内存位置,因此当stringA
稍后更改时,stringB
也会这样做。
我也尝试了strcpy(stringB,stringA)
,但似乎如果stringB
未初始化为足够大的数组,则会出现段错误。我对C字符串没有超级经验,我错过了一些明显的东西吗?如果我只是将stringB
初始化为char *stringB[23]
,因为我知道我永远不会有超过22
个字符的字符串(并允许空终止符),这是正确的方法吗?如果检查stringB
是否与其他C字符串相等,那么额外的空格是否会影响任何内容?
(在这里使用字符串不是解决方案,因为我需要最少的开销并且可以轻松访问单个字符)
答案 0 :(得分:16)
您可以使用strdup()
返回C字符串的副本,如:
#include <string.h>
const char *stringA = "foo";
char *stringB = NULL;
stringB = strdup(stringA);
/* ... */
free(stringB);
你也可以使用strcpy()
,但是你需要先分配空间,这不是很难做到但如果没有正确完成会导致溢出错误:
#include <string.h>
const char *stringA = "foo";
char *stringB = NULL;
/* you must add one to cover the byte needed for the terminating null character */
stringB = (char *) malloc( strlen(stringA) + 1 );
strcpy( stringB, stringA );
/* ... */
free(stringB);
如果您无法使用strdup()
,我建议您使用strncpy()
代替strcpy()
。 strncpy()
函数最多可复制 - 最多 - n
个字节,这有助于避免溢出错误。但是,如果strlen(stringA) + 1 > n
,您需要自己终止stringB
。但是,一般来说,你会知道你需要什么尺寸的东西:
#include <string.h>
const char *stringA = "foo";
char *stringB = NULL;
/* you must add one to cover the byte needed for the terminating null character */
stringB = (char *) malloc( strlen(stringA) + 1 );
strncpy( stringB, stringA, strlen(stringA) + 1 );
/* ... */
free(stringB);
我认为strdup()
更清洁,我自己,所以我尝试在专门处理字符串的地方使用它。我不知道POSIX /非POSIX方法是否有严重的缺点,性能方面,但我不是C或C ++专家。
请注意,我将malloc()
的结果转换为char *
。这是因为您的问题被标记为c++
问题。在C ++中,需要从malloc()
转换结果。但是,在C中,你不强制转换它。
修改强>
你去了,有一个复杂因素:strdup()
不在C或C ++中。因此,请将strcpy()
或strncp()
与预先调整大小的数组或malloc
- ed指针一起使用。无论您在哪里使用该功能,使用strncp()
代替strcpy()
都是一个好习惯。它将有助于减少出错的可能性。
答案 1 :(得分:3)
如果我只是将stringB初始化为char * stringB [23],因为我知道我永远不会有超过22个字符的字符串(并允许空终止符),这是正确的方法吗?
几乎。在C中,如果你确定字符串永远不会太长:
char stringB[MAX+1];
assert(strlen(stringA) <= MAX));
strcpy(stringB, stringA);
或者,如果字符串可能太长:
char stringB[MAX+1];
strncpy(stringB, stringA, MAX+1);
if (stringB[MAX] != '\0') {
// ERROR: stringA was too long.
stringB[MAX] = '\0'; // if you want to use the truncated string
}
在C ++中,您应该使用std::string
,除非您已经证明开销过高。许多实现都有一个“短字符串优化”,这将避免短字符串的动态分配;在这种情况下,使用C风格的数组几乎没有开销。访问单个字符与使用C风格的数组一样方便;在这两种情况下,s[i]
都会将位置i
的角色作为左值。复制变为stringB = stringA;
,没有未定义行为的危险。
如果您确实发现std::string
不可用,请考虑std::array<char,MAX+1>
:包含固定大小数组的可复制类。
如果检查stringB是否与其他C字符串相等,那么额外的空格是否会影响任何内容?
如果您使用strcmp
,它将在最短字符串的末尾停止,并且不会受到额外空间的影响。
答案 2 :(得分:2)
如果你想用纯C风格而不是:
char* new_string = strdup(old_string);
free(new_string);
如果你想用(种)C ++风格:
char* new_string = new char[strlen(old_string) + 1];
strcpy(new_string,old_string);
delete[] new_string;
答案 3 :(得分:0)
您可能正在寻找strncpy
,它允许您复制字符串中的第一个n
字符。只需确保在复制到字符串的位置n处添加空终止符。