2011-01-14 2 views
0

В моей программе на C я пытаюсь скопировать массив символов в другой массив, удалив первый элемент (элемент 0).Копирование массивов в C

Я написал:

char array1[9]; 
char array2[8]; 
int i, j; 

for(i = 1, j = 0 ; i < 10, j < 9; i++, j++){ 
     array2[j] = array1[i]; 
} 
printf(array2); 

При печати array2, это дает мне переполнение стека.

Любые идеи?

+1

Вы можете инициализировать для петель, как это? Я бы просто сделал для (i = 0; i <8; i ++) {array2 [j] = array1 [j + 1]; } – Shaded

+0

Ummm, первый индекс массива C равен 0. Последний индекс - размер-1. Таким образом, вы переполняете массив2, когда вы назначаете 'array2 [8]'. Кроме того, ваше состояние с оператором запятой неверно, помните, что оператор запятой выбрасывает первое значение. Вместо этого вы хотите '&&'. – derobert

ответ

2

Ваша строка не завершена нулевым символом, поэтому, когда она печатается, она продолжает печатать символы, предшествующие 8, которые вы выделили, и ищет их, но до этого времени заканчивается пространство стека. Вы также пишете на один символ больше, чем вы выделили, и ваши условия должны быть «объединены» с && - a , игнорирует результат первого выражения. Вы также должны избегать использования строковой переменной в качестве форматирования строк до printf.

Вот ваш код fixed:

char array1[10] = "123456789"; 
char array2[9]; 
int i, j; 
for(i = 1, j = 0 ; i < 10 && j < 9; i++, j++){ 
     array2[j] = array1[i]; 
} 
printf("%s\n", array2); 

Вы также можете упростить цикл, используя единый индекс переменной i и индексации array2 с i+. Вы также можете полностью удалить цикл, используя strncpy, но имейте в виду, что если n меньше длины строки + 1, он не добавит нулевой ограничитель.

+0

В C, в любое время, когда вы печатаете строку (нелитерал) и получаете переполнение стека, первое, что вы должны проверить, это то, что строка правильно завершена нулем. –

0

Когда вы говорите printf(array2), он считает, что он печатает строку с нулевым символом. Поскольку есть (возможно) нет \0 в array2, printf продолжается до конца array2, блуждая по памяти, он не должен.

0

Для дальнейшего расширения ответа marcog: вы объявляете массив 1 с 9 элементами, 0-8, а затем записываете из 0-9 (10 элементов). То же самое с array2.

3

2 вопроса: Во-первых, при печати строки с printf и при работе с другими стандартными строковыми строками C, ваши массивы char должны быть завершены с нулевыми значениями, чтобы функции знали, где заканчивается строка. Вы также пишете один за концом своих массивов.

Во-вторых, при использовании printf почти всегда Плохая идея использовать строку, которую вы хотите распечатать, как строку формата. Использовать

printf("%s", array2); 

вместо этого. Если вы используете printf, как и в исходном примере, и на него может влиять массив2, ваша программа, скорее всего, уязвима к уязвимости строки формата.

+0

+1 о% s. Printf общей строки может предоставить вектор атаки, если «плохой парень» может предоставить строку. Они могут помещать символы формата в строку и заставлять переполнение стека и, вероятно, запускать свой собственный код. –

+0

Или вы можете использовать 'puts()', если вы не делаете никакого форматирования (хотя я признаю, что я обычно использую 'printf ("% s ", xxx)'). –

2

Использование тетсру():

memcpy(array2, &array1[1], 8); 

Thats проще.

0

Просто используйте strcpy() (если они обе строки!) strcpy() хочет указатель на источник и указатель на пункт назначения.Если вы хотите, чтобы пропустить первый элемент исходного массива просто передать source + 1:

char source[] = "ffoo"; 
char dest[] = "barbar"; 

strcpy(dest, source + 1); 

// now dest is "foo" (since the ending \0 is copied too) 

printf("\n%s\n", dest); 
+0

'strncpy', вероятно, лучше, или даже' strlcpy', если он доступен. – user470379

1

Это не нужно использовать дополнительные array2 как

printf("%.8s",array1+1); 
Смежные вопросы