2015-11-14 1 views
1

Вот мой кодстрока длиннее, чем ожидалось в C

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

int main(){ 
    char pal[8] = "ciaooaic"; 
    char pal1[7] = "ciaoaic"; 
    int lenPal = strlen(pal); 
    int lenPal1 = strlen(pal1); 
    printf("strlen('%s'): %d\n", pal, lenPal); 
    printf("strlen('%s'): %d\n", pal1, lenPal1); 
    return 0; 
} 

Проблема заключается в том, что, когда я запускаю этот код выход:

strlen('[email protected]'): 11 
strlen('ciaoaic'): 7 

Первая строка имеет также другой непечатаемую полукокса между P и @. Я ноб, поэтому, возможно, я пропустил что-то очевидное. Кто-нибудь может мне помочь?

редактировать:

просто дать одно дополнительное место, как символ приятелем [9] = "ciaooaic"; char pal1 [8] = "ciaoaic";

Это работает, но почему? Я понимаю, что должно быть место для \ 0, но «ciaoaic» работает без него ...

+0

просто дать одно дополнительное места, как 'полукокса дружка [9] =«ciaooaic»; char pal1 [8] = "ciaoaic"; ' – ncm

+2

Потому что из-за неопределенного поведения ваш код может выдавать какой-либо результат (_even correct output_). – ameyCU

+0

Когда вы инициализируете строки, например.'char pal [] =" ciaooaic "; компилятор будет включать в себя нуль-терминатор в конце (примечание:' '\ 0'' и' 0' эквивалентны. Когда вы указываете размер, например. 'pal [8]', вы ограничиваете размер массива только этим размером. Если вы случайно заполняете их символами и не оставляете места для нуля, компилятор счастлив, потому что он доверяет вам, что вы имели в виду. Если по случайности, следующий символ, следующий за «char pal [8] =« ciaooaic »;' в памяти - '0', тогда у вас случайно есть строка с завершающим нулем. Не рассчитывайте на то, что регулярно происходит ... –

ответ

4

1. Вы не делаете оставляйте пробелы для нулевого ограничителя, когда вы проходите м strlen(), поэтому ваш код демонстрирует неопределенное поведение -

char pal[8] = "ciaooaic"; 
char pal1[7] = "ciaoaic"; 

Оставьте пространство для '\0'. Объявить и инициализировать, как это -

char pal[9] = "ciaooaic"; 
char pal1[8] = "ciaoaic"; 

2. И strlen() возвращает size_t не int, так пишут, как это -

size_t lenPal = strlen(pal); 
size_t lenPal1 = strlen(pal1); 

и использовать %zu спецификатор для печати обе эти переменные.

+0

'size_t' - это просто' unsigned int', почему они разные? – DMaster

+1

@Dmaster: потому что 'unsigned int' не является' int'. И 'size_t' также может быть' unsigned long'. – usr2564301

+1

@DMaster Это реализация, определяющая, каким он будет тип, и есть и другие неподписанные типы. – ameyCU

2

Вы не оставили места для символа завершения NULL \0.


Либо увеличить размер массива по 1

char pal[9] = "ciaooaic"; 
char pal1[8] = "ciaoaic"; 

ИЛИ

Не указывайте длину на всех

char pal[] = "ciaooaic"; 
char pal1[] = "ciaoaic"; 
0

Оба вышеуказанных ответа достаточны, чтобы решить ваши сомнения. Увеличьте длину как pal, так и pal1 на единицу, так как там нет места для назначения нулевого символа ('\ 0') в конце. Однако есть небольшая хитрость, чтобы напечатать не нуль символа с помощью PRINTF

printf("strlen('%.*s'): %d\n",8, pal, lenPal); 
printf("strlen('%.*s'): %d\n",7, pal1, lenPal1); 

Ссылки на выше трюк: BRILLIANT