Значение ASCII = 0 и '\ 0' - PullRequest
0 голосов
/ 09 июня 2018

Я прочитал этот пост .Но когда я попытался:

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

вместо получения:

before null 

, я получил:

before null   after null

Поэтому мой вопрос: действительно ли значение ASCII 0 действительно равнов '\ 0'?

Ответы [ 3 ]

0 голосов
/ 09 июня 2018

printf не приведет к завершению строки формата printf в этой позиции символа для спецификатора формата %c при заданных значениях 0 или '\0'.Вместо этого вывод терминала для nul обычно будет заполнителем (например, space или подобным)

Однако вы можете вставить nul в строку и затем вывести строку, используя %s спецификатор формата и видим, что на самом деле десятичное 0 на самом деле является значением ASCII для эквивалентного символа ASCII '\0' и завершит строку вточка нуль-символа (см .: www.ASCIItable.com ), например,

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

Пример использования / Вывод

$ ./bin/str_printf_null
before null %c after null

using 0 : 'before null '
using \0: 'before null '
0 голосов
/ 09 июня 2018

Значение ASCII 0 фактически равно \0?

Да


Различия в том, как строки хранятся в памяти и обрабатываются функциямикак printf() важны.

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

Оба хранятся в памяти с неявным символом \0 в конце.Тот факт, что второй имеет явный символ \0 в середине, меняет положение вещей.

printf() будет сканировать строку до " the end ", печатая компоненты по ходу ... в C " конец " обычно означает до первого \0 / nul символа.

В первом варианте printf() копирует символы в выводпока он не достигнет директивы %c, в этот момент он просматривает аргументы, которые были переданы функции ... он может обнаружить, что вы дали '\0', или он может обнаружить, что вы дали '+' - в любом случае,он копирует это в вывод.Затем он продолжит копирование символов в вывод, ища " конец " строки.

Во втором варианте printf() начнет копирование символов в вывод, найдет« конец » (обозначается \0) и останов.

Если бы вы использовали snprintf(), то результаты / выходные данные содержали бы следующее: (опять же,с неявным \0 окончанием)

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

Если бы вы впоследствии напечатали оба из них, они бы выглядели одинаковыми, но содержимое памяти было бы другим.

Однако вывод printf() - это терминал (или файл) ... что происходит с \0, зависит от вашего эмулятора терминала ... оно может просто не отображаться, оно может отображаться как пробел,или у него может быть забавный символ коробки ...

Важно отметить, что это происходит во время выполнения, а не во время компиляции.

0 голосов
/ 09 июня 2018

Причина в том, что printf не фактически заменяет "Hello %s", "World" на "Hello World", а затем печатает их все. Вместо , он печатает "Hello ", затем "World" подряд каждый символ соло , в порядке

Если вы когда-либо пытались напечатать один null символиспользуя putchar(), вы заметите, что вместо этого он печатает пробел, поэтому printf печатает пробел и на его основе.

Обратите внимание, что он напечатает ничего в других системах (например, Linux).

Пример кода того, как на самом деле работает 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);

Итак, возвращаясь к вашему вопросу,Он будет печатать каждый символ, а когда дело доходит до аргумента 0, который равен null , putchar(), либо ставит пробел, либо ничего на основе вашей системы.

Вы можете сказать, чтоprintf аргументы не действительно не имеют никакого отношения к исходной строке, чтобы завершить ее, они не знают друг друга.
как, например, когда вы printf("Hello %s, from SO!", "World");, "World" на самом деле заканчивается в конце с \0, но завершается только собой, а не другим , from SO!.

Да , 0 это '\0'.они одного персонажа.

...