2013-05-21 5 views
3

Согласно моему коду, я предполагаю, что каждый греческий символ хранится в 2 байтах. sizeof возвращает размер каждого символа, как (т.е. SizeOf int)sizeof character и strlen string несоответствие

Как strlen обратный ? [Заставляет меня думать, что каждый символ занимает 2 байта] (не должно быть 4 * 8 = 32, так как оно подсчитывает количество байтов.)

Также, как printf("%c",bigString[i]); печатать каждый символ должным образом? Должен ли он читать 1 байт (символ), а затем отображать из-за %c, почему в этом случае греческий символ не разбивается.

strcpy(bigString,"ειδικούς");//greek 
sLen = strlen(bigString); 
printf("Size is %d\n ",sizeof('ε')); //printing for each character similarly 
printf("%s is of length %d\n",bigString,sLen); 
int k1 = 0 ,k2 = sLen - 2; 

for(i=0;i<sLen;i++) 
printf("%c",bigString[i]); 

Выход:

Size is 4 
ειδικούς is of length 16 
ειδικούς 

ответ

10
  1. Символьные литералы в C имеют тип int, поэтому sizeof('ε') такое же, как sizeof(int). Немного. Вы играете с огнем в этом утверждении. 'ε' будет многоканальный литерал, который не является стандартным и может вернуться, чтобы укусить вас. Будьте осторожны с использованием расширений, подобных этому. Клэнг, например, не примет эту программу с этим литералом. GCC дает предупреждение, но все равно скомпилирует его.

  2. strlen возвращает 16, так как это число байтов в вашей строке перед нулевым терминатором. Ваши греческие символы все 16 биты длиной в UTF-8, так что ваша строка будет выглядеть примерно так:

    c0c0 c1c1 c2c2 c3c3 c4c4 c5c5 c6c6 c7c7 0 
    

    в памяти, где c0c0, например, два байта первого символа. В вашей строке есть одиночный байт с нулевым завершением.

  3. printf похоже на работу, так как ваш терминал поддерживает UTF-8. Вы : печать каждого байта отдельно, но терминал интерпретирует первые два отпечатка как один символ и так далее. Если вы измените что printf вызова:

    printf("%d: %02x\n", i, (unsigned char)bigString[i]); 
    

    Вы увидите байты в байтах поведения вы ожидаете.

+0

Но почему 'strlen' дает' 16'? Есть 8 символов типа 'int' shouldnt, которые дают 4 * 8 = 32? –

+0

№ Символьный литерал - это 'int'. Символы в строке имеют любой размер, который им нужен - в вашем случае это выглядит как два байта за штуку. –

+0

btw, sizeof ('ε') в визуальной студии печатает 1 ... и в любом случае это 'ε' не является строковым литералом, а символьным символом. –