printf with %s to include null characters

2020-04-02 08:08发布

I need to concatenate some strings, and I need to include NULL bytes. I don't want to treat a '\0' as a terminating byte. I want to save my valuable NULL bytes!

In a code example, if

    char *a = "\0hey\0\0";

I need to printf in a format that will output "\0hey\0\0".

-AUstin

标签: c string printf
3条回答
聊天终结者
2楼-- · 2020-04-02 08:49

How about:

int i;
for(i = 0; i < 4; i++)
    printf("%c", a[i]);

If you want a 'printf-like' function to use this when you specify %s in a format string you could include the above code in your own function. But as @Neil mentioned, you'll struggle finding an alternative to looking for null bytes to determine the length of strings. For that I guess you could use some kind of escape character.

查看更多
够拽才男人
3楼-- · 2020-04-02 08:54

The issue here is that the length of the string a cannot be easily determined. For example, your code..

char *a = "\0hey\0\0";

.. allocates seven bytes to the string, the last being the NULL terminator. Using a function like strlen would return 0.

If you know the precise length of the string, then you can write or iterate over the bytes thus:

#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

But you have to know about the 6.

The alternative is not to use NULL-terminated strings, and instead implement an alternative storage mechanism for your bytes; for example a length-encoded array.

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

Graceless, but hopefully you get the idea.

Edit: 2011-05-31

Rereading the question I just noticed the word "concatenate". If the NULL characters are to be copied faithfully from one place in memory to another (not backslash-escape), and you know the total number of bytes in each array beforehand, then you can simply use 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 */
}
查看更多
欢心
4楼-- · 2020-04-02 09:03
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);
查看更多
登录 后发表回答