получить доступ к элементам строки после `\ 0` - PullRequest
1 голос
/ 04 апреля 2020

Недавно я видел код, в котором сортировалась строка, и \0 (так как он имеет наименьший код ASCII) пришел первым из строки.

Но с использованием спецификатора формата %c истинное значение отсортированная строка была напечатана, но я проверил с помощью %s и ничего не было напечатано.

Так вот мой вопрос, если я добавлю \0 в строку (в то время как у меня есть допустимое значение в моей строке после терминатора ), могу ли я получить к этим значениям что-то вроде %c, это безопасно? И будет ли этот ответ всегда или он просто отвечал из-за UB?

Вот пример:

int main()
{
    char a[8]="abcdefg";
    char b[8];
    for (int i = 0; i < 8; i++)
    {
        b[7-i] = a[i];
    }
    for (int i = 0; i < 8; i++)
        printf("%c ", b[i]);
    printf("%s", b);
}

В приведенном выше примере printf("%c ", b[i]); печатает строку отверстия, даже после \0.

Во втором printf("%s", b); ничего не печатается?

На самом деле я хочу знать, является ли использование первого printf верным и законным?

Ответы [ 3 ]

3 голосов
/ 04 апреля 2020

char a[8]="abcdefg";

Примечание: a[7] содержит '\0' (добавляется автоматически).

char b[8];
for (int i = 0; i < 8; i++)
{
    b[7-i] = a[i];
}

Примечание: b является обратным к a => b[0] содержит нулевой символ ('\0')

Теперь перейдем к вашим вопросам:

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

Это печатает b символ за символом, но не как целая строка. В этом нет проблем.

И результат будет выглядеть примерно так:

<empty> g f e d c b a

Это пустое пространство, потому что b[0] является нулевым символом .

во втором одном printf ("% s", b); ничего не печатается?

Опять же, b[0] содержит нулевой символ, т.е. первый символ этой строки - \0. Поэтому он рассматривается как пустая строка, хотя и содержит текст. Нулевой символ обозначает конец строки.

На самом деле я хочу знать, является ли использование первого printf верным и допустимым?

Конечно, это можно рассматривать как печать массива символов Не каждый массив символов должен быть «строкой»!

1 голос
/ 04 апреля 2020

Это решение использует +1, чтобы пропустить первый нежелательный терминатор '\0' и прецизионную часть спецификатора формата, чтобы обеспечить печать только желаемой длины строки (которую я предполагаю известной, поскольку размер массив фиксирован).

#include <stdio.h>

int main()
{
    char a[8]="abcdefg";
    char b[8];
    for (int i = 0; i < 8; i++)
    {
        b[7-i] = a[i];
    }
    printf("%.7s", b+1);
}

Это работает, потому что при вызове printf() параметр b обрабатывается как указатель на char, а +1 пропускает первый из этих char s, который является нежелательным терминатором.

Затем используется '%s' с расширенными опциями. Спецификатор точности .7 теперь устанавливает минимальную ширину (т. Е. Не заполнение) пустой левой стороной . и максимум 7 символов для печати справа от части ..

Таким образом, можно напечатать строку с помощью %s и удалить терминатор.

В случае, если длина является динамической c (например, вы хотите использовать изначально неизвестную длину a) Вы можете перейти на следующий уровень сложности и использовать версию точности *. Это позволило бы поместить «7» в переменную.

0 голосов
/ 04 апреля 2020

Строка - это просто массив символов. Так что, пока вы не go выходите за границы массива, все четко определено.

Это, конечно, требует от вас знать «емкость» строки.

...