2013-11-18 2 views
-1

Я хочу скопировать X в Y слова строки в массив out *.Назначение части строки char * в C

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 [email protected]. Почему появляются невидимые символы после содержимого, которое я скопировал, не предполагается, что это массив из 9? Я ожидал, что выход будет

LO WORLD! 
+2

Значит, вы хотите 'strncpy'? –

ответ

1

мелочью, но строковые литералы имеют тип char* (или const char* в C++), а не unsigned char* - это может быть то же самое в своей реализации, но они не» должно быть.

Кроме того, это не так:

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

Строка фактически занимает байт - есть дополнительный, скрытый '\0' в конце концов, называется nul байт, который знаменует собой конец строка. Эти nul-терминаторы очень важны, потому что, если их нет, тогда многие функции библиотеки C, которые манипулируют строками, будут продолжаться до тех пор, пока они не попадут в байт со значением, равным '\0', - и поэтому может закончиться чтением или попиранием бит памяти они не должны делать. Это называется переполнением буфера и является классической ошибкой (и эксплуатационной проблемой безопасности) в программах на языке C.

В вашем примере вы не включили этот nul-терминатор в свою скопированную строку, поэтому printf() просто продолжает идти, пока не найдет один, следовательно, тарабарщина, которую вы видите. В общем, неплохо было бы использовать функции библиотеки C для управления строками C, если это возможно, поскольку они осторожны, чтобы добавить терминатор для вас. В этом случае strncpy от string.h делает именно то, что вам нужно.

2

В C вы должны прекратить вашу строку со значением 0x00 поэтому строка длиной 9 требуется десять байтов для хранения его с последним набором 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

Строки C должны быть пустыми. Вы создали массив, достаточно большой для 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 для копирования строк.

1

9 символьная строка нуждается в 10 байтах, потому что она должна быть нулевой (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); 
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); 
Смежные вопросы