2015-12-14 2 views
21

По какой-то причине мой второй массив символов (var2) сливается с первым (var1). Вот мой код:Мои массивы символов сливаются в C

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

int main()  
{ 
    char var1[5] = "Hello"; 
    char var2[5] = "World"; 

    printf("This program can write:\t%s\t%s\n", var1, var2); 
    getch(); 
    return 0; 
} 

после компиляции, я получил следующую печать:

Эта программа может написать: Hello WorldHello

Когда я изменил код printf("This program can write:\t%s\n", var2); I получил следующую печать:

Эта программа может написать: WorldHello

Таким образом, ясно, что var1 объединяется с var2.

Это какая-то ошибка компилятора. Если да, то как я могу это исправить? Я попытался переустановить MINGW, но я все равно получаю те же результаты.

Большое спасибо

+9

Не указывать размер массива. Пусть компилятор имеет размер 6 с символом 'char var1 [] =" Hello ";' который включает в себя конечный нулевой символ. – chux

+12

Большинство компиляторов должны были предупредить об этом, кстати. – Dummy00001

+1

Ваши массивы нуждаются в еще одном символе, добавленном к концу, чтобы обнулить их. printf будет искать конец строки, используя символ NULL, который не имеет строки «Hello». Попробуйте изменить 'var1' на размер 6 и изменить« Hello »на« Hello \ 0 ». Затем сделайте то же самое для 'var2' – Gophyr

ответ

36

Строки на самом деле представляют собой одномерный массив символов , завершаемый нулевым символом '\ 0'. Таким образом, строка с нулевым завершением содержит символы, которые содержат строку, за которой следует нуль.

Следующее объявление и инициализация создают строку, состоящую из слова «Hello». Чтобы удерживать нулевой символ в конце массива, размер массива символов, содержащий строку, больше, чем количество символов в слове «Hello».

char var1[6] = {'H', 'e', 'l', 'l', 'o', '\0'}; 

Вы можете более просто сделать:

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

int main()  
{ 

char var1[] = "Hello"; 
char var2[] = "World"; 

printf("This program can write:\t%s\t%s\n", var1, var2); 
getchar(); 
return 0; 

} 

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

+1

вы могли бы добавить это в конец последнего предложения «... если массив достаточно длинный, чтобы содержать« \ 0 », иначе« \ 0 »будет удаляться, а не перезаписывать другую переменную». Спасибо :) – ztk

+2

Ohh Да, я полностью забыл о «\ 0». Прошло много лет с тех пор, как я последний раз программировал C. Большое спасибо. – OMAX

+4

Только ответ, содержащий '[]', который я ценю (но мне не разрешено говорить, как я показал эту оценку). –

8

Вы забыли включить де \0, который указывает конец строки, поэтому обновление размер массивов плюс один будет делать трюк:

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

int main()  
{ 
    char var1[6] = "Hello"; 
    char var2[6] = "World"; 

    printf("This program can write:\t%s\t%s\n", var1, var2); 
    getchar(); 
    return 0; 
} 

Печатается:

Эта программа может написать: Hello World

+0

Спасибо, мне это очень помогло. – OMAX

+3

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

+0

@ Voo, что вы думаете, это I-D? Если вы объявите размер массива большим, чем требуется инициализатором, все остальные элементы инициализируются до нуля. Даже если они были неинициализированы, запись все равно будет определена, а чтение будет * Undefined Behavior * not ID, –

8

При использовании %s в качестве спецификатора формата в printf, он считывает символ из памяти и останавливается при нахождении символа '\0'. Если он не найдет символ '\0', он будет читать до тех пор, пока не найдет символ '\0' где-нибудь в памяти.

В приведенном выше фрагменте var1 и var2 представлены массивы символов длины 5.Поскольку вы используете %s в качестве спецификатора формата, вам необходимо завершить их с помощью '\0'. Это можно сделать, увеличив размер массивов. Это добавит '\0' символ по умолчанию

char var1[6] = "Hello"; 
char var2[6] = "World"; 

Чувствуете разницу между char var1[5] = "Hello"; и char var1[6] = "Hello";

+--------+--------+--------+--------+--------+ 
|  |  |  |  |  | 
| 'H' | 'e' | 'l' | 'l' | 'o' | char var1[5] = "Hello"; 
|  |  |  |  |  | 
+--------+--------+--------+--------+--------+ 





+--------+--------+--------+--------+--------+--------+ 
|  |  |  |  |  |  | 
| 'H' | 'e' | 'l' | 'l' | 'o' | '\0' | char var1[6] = "Hello"; 
|  |  |  |  |  |  | 
+--------+--------+--------+--------+--------+--------+