Должен ли массив символов быть на один байт больше, чем вы собираетесь использовать? - С - PullRequest
1 голос
/ 18 февраля 2011

Я начал изучать C и немного запутался, когда дело доходит до массивов.

#include <stdio.h>

int main()
{
    int i;
    char j[5];

    for (i = 0; i < 5; i++)
    {
        j[i] = 'a';
    }

    printf("%s\n", j);
}

Запуск этого кода выводит

aaaaa♣

Я читал, что charмассив должен быть на один байт длиннее строки, чтобы компилятор мог поместить \0 в конце.Если я заменю код следующим:

#include <stdio.h>

int main()
{
    int i;
    char j[5];

    for (i = 0; i < 4; i++)
    {
        j[i] = 'a';
    }

    printf("%s\n", j);
}

Вывод, который я получаю:

aaaaa

Массив char на один байт длиннее, чем я использую.Я подозреваю, что именно поэтому я не вижу этот нечетный символ в конце строки?

Я пытался проверить эту теорию с помощью следующего кода:

#include <stdio.h>

int main()
{
    int i;
    char j[5];

    for (i = 0; i < 4; i++)
    {
        j[i] = 'a';
    }

    for (i = 0; i < 4; i++)
    {
       printf("%d\n", j[i]);
    }
}

Но ввывод я не вижу ноль байт.Это потому, что он будет добавлен только в случае вывода в виде строки?

97
97
97
97

Ответы [ 5 ]

5 голосов
/ 18 февраля 2011

Ваша задача - добавить нулевой байт. Компилятор не обязательно сделает это за вас. Локальные переменные обычно остаются неинициализированными во время выполнения.

int i;
char j[5];    /* five uninitialized characters, could be anything */

for (i = 0; i < 4; i++)
{
    j[i] = 'a';
}

j[4] = '\0';  /* explicitly add null terminator */

Обратите внимание, что если вы используете инициализатор строки вместо установки каждого символа вручную, компилятор будет обрабатывать добавление нулевого терминатора для вас:

char j[5] = "aaaa";  /* initialize to {'a', 'a', 'a', 'a', '\0'} */
1 голос
/ 18 февраля 2011

The char array is one byte longer than I'm using. I suspect this is why I don't see that odd character at the end of the string?

Не совсем, если вы добавили только 4 элемента, то 5-й случайно совпадет. Для 5-го символа вы должны были сделать это j[4] = '\0';, в этом случае на следующем адресе памяти могло быть значение \0.

But, in the output, I see no nullbyte

Это потому, что вы печатаете только первые 4 символа (см. Ваш цикл).

1 голос
/ 18 февраля 2011

В обоих этих случаях вы печатаете массив char без 0-завершения , используя функцию, которая ожидает 0-завершения.

Добавляйте '\ 0' к каждой строке (исключаяодин с 5 символами)

for (i = 0; i < 4; i++)
    {
        j[i] = 'a';
    }
j[4] = '\0';

Кроме того, ваш массив имеет длину 5 символов / байт, а не 6. Вы можете хранить в нем 4 символа + 0-окончание, а не 5 символов + 0-окончание.

Для цикла %d вы печатаете каждое 'a' как целое число.Строка "% d \ n", которую вы передаете в printf, автоматически заканчивается на 0, поэтому на выходе получается 97\n

0 голосов
/ 18 февраля 2011

Нет нулевого байта, потому что вы напечатали только первые четыре байта.Нуль в пятом.Кроме того, если вы не используете строку, сгенерированную компилятором (например, «строка»), нулевой байт должен быть установлен вручную.Единственная причина, по которой ваш код работает сейчас, заключается в том, что память, в которую помещается строка, уже равна 0.Что касается требования нулевого байта, строки c используют его, чтобы указать конец строки.Он не всегда будет использоваться для массивов, но должен присутствовать всякий раз, когда массив интерпретируется как строка.

0 голосов
/ 18 февраля 2011

Вам нужно добавить нулевой символ в себя при построении таких строк.

Единственный раз, когда вы этого не сделаете, это когда вы устанавливаете строковый литерал ...

char *str = "this is a string";

Компилятор выведет \0 в конце для вас.

CodePad.org

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...