C语言 printf 与 %s 以包含空字符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6093660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:44:11  来源:igfitidea点击:

printf with %s to include null characters

cstringprintf

提问by austin

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!

我需要连接一些字符串,并且需要包含 NULL 字节。我不想将 '\0' 视为终止字节。我想保存我宝贵的 NULL 字节!

In a code example, if

在代码示例中,如果

    char *a = "
int i;
for(i = 0; i < 4; i++)
    printf("%c", a[i]);
hey
char *a = "
#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
hey
#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, "
#include <string.h>
char *a = "
char *a="##代码##hey##代码####代码##";
int alen = 7;

char buf[20] = {0};
int bufSize = 20;

int i=0;
int j=0;
while( i<bufSize && j<alen )
{
    if(a[j]=='##代码##') {
        buf[i++]='\';
        buf[i++]='0';
        j++;
    }
    else {
        buf[i++] = a[j++];
    }
}

printf(buf);
hey##代码####代码##"; /* 6 */ char *b = "word##代码##up yo"; /* 10 */ char *c = "##代码####代码####代码####代码##"; /* 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 */ }
hey##代码####代码##" }; my_printf(&foo); }
##代码##";
##代码##";

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

我需要以输出“\0hey\0\0”的格式打印。

-AUstin

-AUstin

回答by sje397

How about:

怎么样:

##代码##

If you want a 'printf-like' function to use this when you specify %sin 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.

如果您希望%s在格式字符串中指定时使用“类似printf”的函数,则可以在您自己的函数中包含上述代码。但正如@Neil 所提到的,您将很难找到替代查找空字节来确定字符串长度的方法。为此,我想您可以使用某种转义字符。

回答by Matty K

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

这里的问题是字符串的长度a不容易确定。例如,您的代码..

##代码##

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

.. 为字符串分配七个字节,最后一个是 NULL 终止符。使用像strlen这样的函数会返回 0。

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

如果您知道字符串的精确长度,那么您可以这样写入或迭代字节:

##代码##

But you have to know about the 6.

但是你必须知道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.

另一种方法是不使用以 NULL 结尾的字符串,而是为您的字节实现另一种存储机制;例如长度编码的数组。

##代码##

Graceless, but hopefully you get the idea.

不优雅,但希望你能明白。

Edit: 2011-05-31

编辑: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.

重读这个问题,我刚刚注意到“连接”这个词。如果要将 NULL 字符从内存中的一个地方忠实地复制到另一个地方(不是反斜杠转义),并且您事先知道每个数组中的总字节数,那么您可以简单地使用memcpy.

##代码##

回答by daalbert

##代码##