Printf с% s для включения пустых символов
Мне нужно конкатенировать некоторые строки, и мне нужно включить NULL байты. Я не хочу рассматривать "\ 0" как завершающий байт. Я хочу сохранить свои полезные NULL байты!
В примере кода, если
char *a = "\0hey\0\0";
Мне нужно напечатать f в формате, который будет выводить "\ 0hey\0\0".
-AUstin
Ответы
Ответ 1
Как насчет:
int i;
for(i = 0; i < 4; i++)
printf("%c", a[i]);
Если вы хотите использовать функцию "printf-like", когда вы указываете %s
в строке формата, вы можете включить приведенный выше код в свою собственную функцию. Но, как сказал @Neil, вы будете пытаться найти альтернативу поиску нулевых байтов для определения длины строк. Для этого я предполагаю, что вы можете использовать какой-то escape-символ.
Ответ 2
Проблема заключается в том, что длина строки a
не может быть легко определена. Например, ваш код..
char *a = "\0hey\0\0";
.. выделяет семь байтов в строку, последний из которых является терминатором NULL. Использование такой функции, как strlen
, вернет 0.
Если вы знаете точную длину строки, вы можете написать или перебрать по байтам, таким образом:
#ifdef ESCAPE_NULLS
int i;
for (i = 0; i <= 6; i++)
if (a[i] == 0)
printf("\\0");
else
printf("%c", a[i]);
#else
write(1, a, 6);
#endif
Но вы должны знать о 6.
Альтернативой является не использование строк с завершающим NULL, а вместо этого реализация альтернативного механизма хранения для ваших байтов; например массивом, закодированным по длине.
#include <stdio.h>
typedef struct {
int length;
char *bytes;
} bytearr;
void my_printf(bytearr *arr)
{
#ifdef ESCAPE_NULLS
int i;
for (i = 0; i <= arr->length; i++)
if (arr->bytes[i] == 0)
printf("\\0");
else
printf("%c", arr->bytes[i]);
#else
write(1, arr->bytes, arr->length);
#endif
}
void main(void)
{
bytearr foo = {
6, "\0hey\0\0"
};
my_printf(&foo);
}
Бессмертный, но, надеюсь, вы получите эту идею.
Изменить: 2011-05-31
Перечитывая вопрос, я просто заметил слово "concatenate". Если символы NULL должны быть скопированы с одного места в памяти на другое (без обратного слэша-побега), и вы знаете общее количество байтов в каждом массиве заранее, вы можете просто использовать memcpy
.
#include <string.h>
char *a = "\0hey\0\0"; /* 6 */
char *b = "word\0up yo"; /* 10 */
char *c = "\0\0\0\0"; /* 4 */
void main(void)
{
char z[20];
char *zp = z;
zp = memcpy(zp, a, 6);
zp = memcpy(zp, b, 10);
zp = memcpy(zp, c, 4);
/* now z contains all 20 bytes, including 8 NULLs */
}
Ответ 3
char *a="\0hey\0\0";
int alen = 7;
char buf[20] = {0};
int bufSize = 20;
int i=0;
int j=0;
while( i<bufSize && j<alen )
{
if(a[j]=='\0') {
buf[i++]='\\';
buf[i++]='0';
j++;
}
else {
buf[i++] = a[j++];
}
}
printf(buf);