2013-05-11 4 views
0

В этом примере программы, иллюстрирующей это поведение strcpy(), я написал строку "S" в большую строку previous, у которой был "Delaware". Но эта перезапись влияет только на первые два символа в исходной строке. Остальная часть исходной строки продолжается иметь те же ценности. Как с этим бороться? (Даже memcpy(), похоже, имеет такое же поведение). Я имею в виду, как превратить оставшиеся символы в 0? Или остальные символы в строке, сохраняющей исходные значения, не имеют побочных эффектов?strcpy() маленькой струны в большую строку оставляет остальную большую строку неизменной. Как с этим бороться?

#include<stdio.h> 
#include<string.h> 

int main() 
{ 
    char previous[10]="Delaware"; 
    printf("The character at position 4 is %c\n",previous[4]); 
    strcpy(previous,"S"); 
    printf("The character at position 4 later is %c",previous[4]); 
} 
+0

Почему вы хотите изменить остальную часть строки на 0? – yngccc

+0

Зачем это делать по умолчанию? Это строковая функция, и строки не связаны с тем, что происходит после нулевого терминатора, так что это просто пустая трата циклов большую часть времени. – chris

+0

'strcpy' также скопирует нулевой терминатор, поэтому, если вы выполните' printf («% s \ n», предыдущий); 'он будет печатать только' S', это предполагает, что место назначения достаточно велико, чтобы также иметь нулевой ограничитель , –

ответ

3

зЬгсру функция делает это:

previous     "S" 
    |     | 
    v     v 
-- -- -- -- -- -- -- -- -- -- -- - 
| D| e| l| a| w| a| r| e|\0| | | S|\0| 
-- -- -- -- -- -- -- -- -- -- -- -- 
^^       | | 
    | |       | | 
    | - - - - - - - - - - - - - - - - 
    |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _| 

оставив память вида:

-- -- -- -- -- -- -- -- -- -- -- - 
| S|\0| l| a| w| a| r| e|\0| | | S|\0| 
-- -- -- -- -- -- -- -- -- -- -- -- 

Дополнительные символы после 0 не будут иметь значения при обращении к предыдущим в таких вещах, как printf. Точно так же, как дополнительное место в памяти после того, как 0 в Делавэре не повлияло на использование предыдущего, ссылаясь на него.

+1

+1 для искусства ASCII, получить инструмент здесь .. [asciiflow] (http://www.asciiflow.com/#Draw) –

+0

@HaIR Не 'strcpy()' получить езду '| S | \ 0 | 'справа после того, как он скопировал его над' De' частью 'Delaware'? Должна ли не уважаемая библиотека работать как 'strcpy()' пустая память памяти '| S | 0 |' после ее использования? –

+0

Нет, это не так. Он ничего не делает для этой памяти. Это сложно, а не strcpyandfree или strcpyandclear (они не существуют, насколько я знаю) – HalR

0

1) Это правильное поведение для strcpy(). Если вы используете значения str * для доступа к строке, вы никогда не увидите ни одного из неизмененных байтов, поскольку на второй позиции (индекс 0) был помещен ограничитель строки ('\ 0'), а функции str * не пройдут конец строки.

2) Это НЕ поведение memcpy(). Если вы memcpy(str2, str1, 10), будет скопировано 10 символов. memcpy(previous, "S", 10) это не очень хорошая идея, однако ;-)

3) Если вы хотите обнулить предыдущими [] до зЬгсра(), попробовать что-то вроде memset(previous, '\0', sizeof(previous))

+0

'memset', а не' bzero'. Последний является устаревшей функцией от задолго до стандартизации C. –

+0

Правда. Я отредактирую свой ответ. –

0

Вы реализуете свою strcpy() функцию? Если это так, не забудьте скопировать нулевой ограничитель из исходной строки в пункт назначения. Нулевой ограничитель - это то, что говорит C, где заканчивается String. Реализация по умолчанию в библиотеке строк делает это, и когда вы распечатываете ее с помощью printf(), она отображает то, что вы ожидаете.

Если распределение памяти является проблема, то вы могли бы free() пространства, занятую previous строки, а затем malloc() достаточно для строки вы копируете, но это перебор в большинстве случаев, если вы действительно не беспокоиться об ограничениях памяти, в которой Если вы, вероятно, не будете использовать библиотеку строк.

0

Остальные символы в строке на самом деле не должно быть никакого эффекта, так как предыдущая строка будет иметь S в качестве первого символа (т.е. предыдущий [0]) и значение NULL в качестве второго. Если ваш код не проверяет определенные символы в строке, это не имеет значения. Однако, если вы действительно хотите, чтобы строка имела скопированное вами значение, а затем все NULL, вы можете очистить строку перед выполнением strcpy.

memset(previous, 0, sizeof(previous)); 
strcpy(previous, "S"); 
1

strcpy также скопировать нулевой символ, так что если вы делаете:

printf("%s\n", previous) ; 

в вашем случае вы будете видеть только S, которые в большинстве случаев достаточно.Если вы действительно хотите обнулить память, прежде чем сделать strcpy вы всегда можете использовать memset перед копией:

memset(previous, 0, sizeof(previous)) ; 
Смежные вопросы