Что происходит, когда вы выводите NUL, зависит от устройства вывода.
Это непечатный символ, т.е. isprint('\0') == 0
; поэтому при выводе на устройство отображения оно не оказывает видимого влияния. Однако, если он перенаправлен в файл (или при вызове fprintf()
), он вставит в файл NUL (нулевой байт); значение этого будет зависеть от того, как файл используется.
При выводе в строку C она будет интерпретироваться как терминатор строки стандартными функциями обработки строк, хотя любые другие последующие спецификаторы формата будут по-прежнему приводить к тому, что данные будут помещены в буфер после NUL, который будет невидим для стандарта функции обработки строк. Это все еще может быть полезно, если в конечном итоге массив не должен интерпретироваться как строка C.
Есть ли риск утечки памяти или других проблем, если я, например, снимать этот NULL в точке в std :: string.c_str ()?
Совершенно неясно, что вы подразумеваете под этим, но если вы предлагаете использовать указатель, возвращаемый std::string.c_str()
в качестве буфера для sprintf()
; нет! c_str()
возвращает const char*
, изменение строки через такой указатель не определено. Это, однако, другая проблема, не связанная со вставкой NUL в строку.
Каковы наилучшие способы избежать этого предостережения (дезинфицировать вход?)
Я изо всех сил пытаюсь придумать обстоятельства, при которых вы могли бы «случайно» написать такой код, так зачем вам остерегаться его !? Вы имеете в виду конкретное обстоятельство? Даже если я нахожу это неправдоподобным и, вероятно, ненужным, в чём тут сложность:
if( c != 0 )
{
printf( "%c", c ) ;
}
или, возможно, более полезный (так как в выводе есть другие символы, которых вы можете избежать)
if( isgraph(c) || isspace(c) )
{
printf( "%c", c ) ;
}
, который будет выводить только видимые символы и пробелы (пробел, '\t'
, '\f'
, '\v'
, '\n'
, '\r'
).
Обратите внимание, что вы также можете рассмотреть isprint()
, а не isgraph(c) || isspace(c)
, но это исключает '\t'
, '\f'
, '\v'
, '\n'
и '\r'