2010-06-24 2 views
0

В проекте шахты (которые по техническим причинам не должны зависеть от каких-либо внешних библиотек или сторонних источников) я поставил следующие test.h:Как сделать printf() правильно печатать двоичный блок из макроса?

static int rc = 0; 
#define TESTCASE(x) if (x) {} \ 
         else \ 
         { \ 
          rc += 1; \ 
          printf("FAILED: " __FILE__ ", line %d - " #x "\n", __LINE__); \ 
         } 

Это отлично работает большую часть времени - если testcase оценивает значение true, ничего не происходит. Если тестовый файл имеет значение false, тестовый файл печатается, включая имя файла и номер строки.

Однако, когда тестовый файл содержит строковый литерал, printf() в макросе TESTCASE настаивает на интерпретации строкового литерала как части строки формата (которая оказалась фатальной для определенного тестового файла).

Теперь я размышляю о различных подходах, чтобы получить printf(), чтобы напечатать все, что есть в x (тестовая строка) дословно, но я пришел пустым. Ближе всего было использовать %c для печати фиксированных чисел символов и передать текстовое поле (#x) в качестве параметра printf() - но я не мог понять, как определить размер #x, особенно если он содержит нулевые байты (что исключает использование strlen()).

Confused, и в недоумении. Помогите?

ответ

3

Как использовать %s как формат, затем передать строгий тестовый пример в качестве параметра, как и для номера строки?

printf("FAILED: %s, line %d - %s\n", __FILE__, __LINE__, #x); 

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

(вы никогда не должны использовать любое значение, а не hardcoded как строка формата для printf: это поднимает ад большую часть времени)

+0

Хороший первый appriach, но что, если строковый литерал в #x содержит нулевые байты? – DevSolar

+0

Я не думаю, что это возможно: нулевой байт не имеет представления, он недопустим в исходном файле C и, следовательно, не может появиться в вашем тестовом примере. (или определение макроса 'TEST_CASE' в вашем вопросе неверно) помните, что оператор' # 'препроцессора является строкатором, он преобразует' abc', который буквально появляется в аргументе макроса '' abc "'. –

+0

И вот я был на полпути, набрав «эй», я мог писать «\ 0» в строковый литерал в любое время », когда понял, что« \ 0 »является * представлением * нулевого байта, а не самой вещи. AAaaargh ... половина моего мозга, должно быть, спала. Конечно, вы абсолютно правы. – DevSolar

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