C 带有%s的printf包含空字符

C 带有%s的printf包含空字符,c,string,printf,C,String,Printf,我需要连接一些字符串,并且需要包含空字节。我不想将'\0'视为终止字节。我想保存我宝贵的空字节 在代码示例中,如果 char *a = "\0hey\0\0"; 我需要以输出“\0hey\0\0”的格式打印F -奥斯汀怎么样 int i; for(i = 0; i < 4; i++) printf("%c", a[i]); inti; 对于(i=0;i

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

在代码示例中,如果

    char *a = "\0hey\0\0";
我需要以输出“\0hey\0\0”的格式打印F

-奥斯汀怎么样

int i;
for(i = 0; i < 4; i++)
    printf("%c", a[i]);
inti;
对于(i=0;i<4;i++)
printf(“%c”,a[i]);

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

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

char *a = "\0hey\0\0";
。。为字符串分配七个字节,最后一个是空终止符。使用类似
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
char*a=“\0hey\0\0”;
int-alen=7;
char buf[20]={0};
int bufSize=20;
int i=0;
int j=0;

while(i你打算如何计算字符串的长度?它是预先确定的。我已经分配了空间,比如8字节。我想使用printf(%s%s%s…)将几个给定大小的字符串拼凑在一起。如果数组中嵌入了空值,它就不是字符串。不要称它为字符串。将它称为(无符号)字符数组(带有嵌入空值)。由于它不是字符串,您无法可靠地在该对象上使用任何字符串函数:无
“%s”
转换为
printf
(或
scanf
),没有
fputs
,没有
fgets
,没有
strcpy
,没有
strcat
,…为什么需要很多代码?这是一个微不足道的for循环?很难找到替代方法。我说很多代码,因为对10个字符串这样做意味着10个for循环。当然不是世界末日。这看起来不太理想,但我承认不是与最理想的人一起工作situation@austin-这不是意味着一个函数和十个调用吗?我建议使用putchar()而不是printf()。字符不需要格式化,所以putchar()是更有效。或者怎么样。这甚至比
putchar
更好;您根本不需要一次循环一个字节。您在响应的第一部分有一个if/else语句。这是否意味着printf(“%c”)在空字节上不起作用?这取决于你是想忠实地将空字节传递给STDOUT,还是反斜杠转义它(这是我读原始问题的方式)。@MattyK:不应该
write(1,a,6);
be
write(1,a,sizeof(char)*6)当然,如果你写的是正确的、可移植的代码。你很容易懒惰,并且假设
sizeof(char)==1
不要把POSIX
write()
和stdio
printf
混在一起。使用
fwrite
。不要使用
printf(%c)
对于单个字节,使用
putchar
!或者更好,搜索下一个
0
并使用
fwrite
通过一个函数调用对所有非零字节进行写入。或者将其复制并转义到本地缓冲区并写入。顺便说一句,
memcpy
不是
strcat
memcpy
返回其未修改的第一个参数,而不是写入位置的结尾。因此,您的更新会重复覆盖
z
的开头。但是,如果使用正确的目标指针,memcpy是作业的正确工具。
#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);
}
#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 */
}
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);