2016-11-14 5 views
1

Мне интересно, как работают Printf и я стараюсь много трюков, как:Поведение Printf с использованием длины subspecifier со строкой

printf("Test 1: %hs\n", "hi"); 
printf("Test 2: %hhs\n", "hi"); 
printf("Test 3: %ls\n", "hi"); 
printf("Test 4: %lls\n", "hi"); 
printf("Test 5: %js\n", "hi"); 
printf("Test 6: %zs\n", "hi"); 
printf("Test 7: %ts", "hi"); 

Я использую Printf с s спецификатора и все длины модификатором (обычно используется с численный speficier (как d/i/u/o ...) и я получаю странный вывод:

Test 1: hi 
Test 2: hi 
Test 3: Test 4: Test 5: Test 6: hi 
Test 7: hi 

это, кажется, что обычные l/ll/j модификаторов длины делают PRINTF ошибку и перестать работать (он не печатает \n, но со всем другим модификатором длиной s, похоже, игнорирует модификатор длины и работает как обычное использование).

Почему это следует за этим поведением?

ответ

3

Ответ undefined behaviour. Спецификатор формата %s не поддерживает ни один из модификаторов длины, которые вы использовали для аргументов, которые вы передаете. Несоответствие Формат спецификатор не определен в C. Когда я компиляции кода с компилятором GCC (gcc -Wall -Wextra -std=c11 test.c), он говорит так:

test.c: In function ‘main’: 
test.c:5:19: warning: use of ‘h’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=] 
printf("Test 1: %hs\n", "hi"); 
       ^
test.c:6:20: warning: use of ‘hh’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=] 
printf("Test 2: %hhs\n", "hi"); 
        ^
test.c:7:19: warning: format ‘%ls’ expects argument of type ‘wchar_t *’, but argument 2 has type ‘char *’ [-Wformat=] 
printf("Test 3: %ls\n", "hi"); 
       ^
test.c:8:20: warning: use of ‘ll’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=] 
printf("Test 4: %lls\n", "hi"); 
        ^
test.c:9:19: warning: use of ‘j’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=] 
printf("Test 5: %js\n", "hi"); 
       ^
test.c:10:19: warning: use of ‘z’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=] 
printf("Test 6: %zs\n", "hi"); 
       ^
test.c:11:19: warning: use of ‘t’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=] 
printf("Test 7: %ts", "hi"); 
+0

* «... не поддерживает ни один из модификаторов длины ...» * - не '% ls' означает, широкий строка? – jww

+0

"** ... вы использовали для аргументов, которые вы передаете. **". не означает, что% ls означает широкую строку? »- Да. – usr

2

только длина модификатора, действительный для использования с %s является l, и это означает, что аргумент имеет тип wchar_t, а не char.

Ни один из hh, h, ll, j, z или t определены для использования с s.

Пожалуйста, смотрите C 2011 online standard, § 7.21.6.1, пункт 7.

Смежные вопросы