ASCII值= 0和' \ 0'

时间:2018-06-09 05:56:41

标签: c ascii null-character

我看过this post。 但是当我尝试时:

  printf("before null %c after null\n", 0);  // (ASCII=0) != '\0' ??

而不是得到:

before null 

我得到了:

before null   after null

所以我的问题是:   ASCII值0实际上等于' \ 0'?

3 个答案:

答案 0 :(得分:5)

  

ASCII值0实际上是否等于\0

字符串存储在内存中以及由printf()等函数处理的差异非常重要。

"before null %c after null\n"
"before null \0 after null\n"

两者都存储在内存中,末尾有一个隐式\0终止符。第二个在中间有一个明确的\0字符的事实改变了事情。

printf()将扫描字符串,直到“结束”,打印组件,因为它在C“结束”通常意味着直到第一个\0 / nul 字符。

使用第一个变体,printf()将字符复制到输出,直到它到达%c指令,此时它会查看给函数的参数...它可能会发现你给了'\0',或者它可能会发现你给了'+' - 无论哪种方式,它都会将其复制到输出中。然后它会继续将字符复制到输出中,寻找字符串的“结束”。

使用第二个变体,printf()将开始将字符复制到输出,将找到“ the end ”(由\0表示),并停止。

如果您使用snprintf(),则结果/输出将包含以下内容:(同样,隐式\0终止)

"before null \0 after null\n"
"before null "

如果您随后打印这两个,它们看起来相同,但内存内容会有所不同。

然而,printf()的输出是终端(或文件)...... \0会发生什么情况取决于您的终端仿真器......它可能根本就没有显示,可能是显示为空格,或者它可能有一个有趣的方框符号......

需要注意的重要一点是,这发生在运行时 - 而不是编译时。

答案 1 :(得分:3)

原因是printf 不是实际上用"Hello %s", "World"替换"Hello World"然后将它们打印出来。 相反,它会在每个字符 solo 的行中打印"Hello "然后"World",按顺序

如果您曾尝试使用null打印单个putchar()字符,请注意它会打印一个空格,这就是printf打印一个空格的原因空间也基于它。

  

请注意,它会在其他系统(例如Linux)上打印 nothing

printf实际工作方式的示例代码。

const char * x;
// while the current char != '\0'
while (*format)
{
    // if the current char == '%'
    if (*format == '%')
    {
        // increment the pointer so we can point to the next char and skip printing '%'
        switch (*(++format)) // then switch that next char (specifier).
        {
        case 'c':
            putchar(va_arg(args, char)); // if the argument is null, then it's putchar(0);
            break;
        case 's':
            // regular operation of printing a string argument.
            x = va_arg(args, const char*);
            while (*x) putchar(*x++);
            break;
        }
        // skips the format specifier so we don't print it (e.g 's', 'c'..)
        *format++;
    }
    // else: isn't a format specfier.
    else
       // print the current char (pointer) of the original string
        putchar(*format++); // increments it for the next operation.
}
va_end(args);

所以回到你的问题,它将打印每个字符,当涉及到 null 的参数0时,putchar()将放置空格或基于空格在你的系统上。

您可以说printf参数不是与原始字符串确实有任何关系以终止它,他们彼此不认识。
就像当你printf("Hello %s, from SO!", "World"); 时, "World"实际上在\0结束时终止,但它会自行终止,而不是其他, from SO!

0'\0'。他们是同一个角色。

答案 2 :(得分:1)

当给定值printf或{{1}时,

%c不会在0 格式说明符的字符位置终止printf格式字符串}。相反,'\0'的终端输出通常是占位符(例如nul等)

但是,您可以在字符串中插入space,然后使用nul 格式说明符输出字符串,并查看实际上 decimal 0实际上是等效ASCII 字符的 %s的ASCII值,并将在 nul-character 处终止字符串(请参阅:{{3 }}),例如

'\0'

示例使用/输出

#include <stdio.h>

#define FMT "before null %c after null\n"

int main (void) {

    char buf[sizeof FMT * 2];

    puts (FMT);

    sprintf (buf, FMT, 0);
    printf ("using 0 : '%s'", buf);
    putchar ('\n');

    sprintf (buf, FMT, '\0');
    printf ("using \\0: '%s'", buf);
    putchar ('\n');

    return 0;
}