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);