将字符串的一部分分配给C中的char *

时间:2013-11-18 04:16:02

标签: c string

我想将字符串的X到Y字复制到out char *数组。

unsigned char * string = "HELLO WORLD!!!" // length 14
unsigned char out[9];
size_t length = 9;
for(i=0 ;i < length ;++i)
{
   out[i] = string[i+3];
}

printf("%s = string\n%s = out\n", string, out);

在查看out的输出时,为什么在我的字符串的某一点之后会出现乱码?我看到字符串为LO WORLD!@。为什么在我复制的内容之后出现了奇怪的字符,是不是应该是9的数组呢?我期望输出为

LO WORLD!

5 个答案:

答案 0 :(得分:2)

在C中,您需要使用0x00值终止字符串,因此长度为9的字符串需要10个字节来存储它,最后一个设置为0.否则您的打印语句会运行到随机数据中。

unsigned char * string = "HELLO WORLD!!!" // length 14
unsigned char out[10];
size_t length = 9;
for(i=0 ;i < length ;++i)
{
   out[i] = string[i+3];
}
out[length] = 0x00;

printf("%s = string\n%s = out\n", string, out);

答案 1 :(得分:1)

C字符串必须以null结尾。您只创建了一个足够大的数组,可以容纳8个字符+空终止符,但是您从未添加过终结符。

因此,您需要分配长度加1并添加终结符。

// initializes all elements to 0
char out[10] = {0};
// alternatively, add it at the end.
out[9] = '\0';

以这种方式思考;你传递了一个表示字符串的char*。你怎么知道它有多长?你怎么看?好吧,在C中,一个哨兵值被添加到最后。这是空终止符。它是如何在C中读取字符串,并将未终止的字符串传递给期望C字符串导致未定义行为的函数。

然后......只需使用strncpy复制字符串。

答案 2 :(得分:1)

9个字符的字符串需要10个字节,因为它必须为null(0)终止。试试这个:

unsigned char out[10]; // make this 10
size_t length = 9; 
for(i=0 ;i < length ;++i)
{
   out[i] = string[i+3];
}
out[i] = 0; // add this to terminate the string

更好的方法就是这一行:

   strncpy(out, string+3, 9);

答案 3 :(得分:1)

如果你想从你的字符串中复制9个字符,你需要有一个10的数组才能做到这一点。这是因为C字符串需要将'\ 0'作为空终止字符。所以你的代码应该像这样重写:

unsigned char * string = "HELLO WORLD!!!" // length 14
unsigned char out[10];
size_t length = 9;
for(i=0 ;i < length ;++i)
{
   out[i] = string[i+3];
}
out[9] = 0;

printf("%s = string\n%s = out\n", string, out);

答案 4 :(得分:1)

一个小问题,但是字符串文字的类型为char*(或C ++中的const char*),而不是unsigned char* - 这些在您的实现中可能是相同的,但它们不是需要。

此外,事实并非如此:

unsigned char * string = "HELLO WORLD!!!" // length 14

该字符串实际占用 15 字节 - 末尾有一个额外的隐藏'\0',称为nul字节,用于标记字符串的结尾。这些nul终结符非常重要,因为如果它们不存在,那么操作字符串的许多C库函数将继续运行,直到它们达到值等于'\0'的字节 - 因此最终可能会读取或践踏他们不应该做的内存。这称为缓冲区溢出,是C程序中的经典错误(以及可利用的安全问题)。

在你的例子中,你没有在你复制的字符串中包含这个nul终结符,所以printf()只是一直持续到它找到一个,因此你看到的是胡言乱语。一般来说,如果可能的话,只使用C库函数来操作C字符串是一个好主意,因为这些都是为您添加终止符。在这种情况下,来自strncpy的{​​{1}}完全符合您的要求。