Подтвердить что ты не робот

Определение строки без нулевого завершения char (\ 0) в конце

Каковы различные способы в C/С++ для определения строки без нулевого завершения char (\ 0) в конце?

EDIT: Меня интересуют только массивы символов, а не строки STL.

4b9b3361

Ответ 1

Обычно, как писал другой плакат:

char s[6] = {'s', 't', 'r', 'i', 'n', 'g'};

или если ваша текущая C-кодировка - ASCII, которая обычно верна (не так много EBCDIC сегодня)

char s[6] = {115, 116, 114, 105, 110, 107};

Существует также сильно игнорируемый способ, который работает только в C (не С++)

char s[6] = "string";

Если размер массива слишком мал, чтобы удерживать конечный 0 (но достаточно большой, чтобы удерживать все остальные символы константной строки), конечный ноль не будет скопирован, но он все еще действителен C (но недействителен С++).

Очевидно, вы также можете сделать это во время выполнения:

char s[6];
s[0] = 's';
s[1] = 't';
s[2] = 'r';
s[3] = 'i';
s[4] = 'n';
s[5] = 'g';

или (то же замечание в кодировке ASCII, как указано выше)

char s[6];
s[0] = 115;
s[1] = 116;
s[2] = 114;
s[3] = 105;
s[4] = 110;
s[5] = 103;

Или используя memcopy (или memmove или bcopy, но в этом случае нет никакой пользы для этого).

memcpy(c, "string", 6);

или strncpy

strncpy(c, "string", 6);

Что следует понимать, так это то, что в C нет строки типа C (в С++ есть объекты строк, но это совсем другая история). Так называемые строки - это просто char массивы. И даже имя char вводит в заблуждение, это не char, а просто своего рода числовой тип. Вероятно, мы могли бы назвать его байтом, но в прежние времена существовало странное аппаратное обеспечение, использующее 9-битные регистры или такие, а байты - 8 бит.

Поскольку char будет очень часто использоваться для хранения символьного кода, дизайнеры C подумали о более простом способе, чем хранить номер в char. Вы можете поместить письмо между простыми кавычками, и компилятор поймет, что он должен хранить этот код символа в char.

Что я имею в виду (например), что вам не нужно делать

char c = '\0';

Чтобы сохранить код 0 в char, просто выполните:

char c = 0;

Поскольку нам очень часто приходится работать с кучей символов переменной длины, дизайнеры C также выбрали соглашение для "строк". Просто поместите код 0, где текст должен заканчиваться. Кстати, есть имя для такого рода строкового представления "строка с нулевым завершением", и если вы видите две буквы sz в начале имени переменной, это обычно означает, что это содержимое является строкой с нулевым завершением.

"C sz strings" не является типом вообще, просто массив символов, как обычно, как, скажем, массив int, но функции манипуляции с строкой (strcmp, strcpy, strcat, printf и многие другие) понимают и используйте соглашение о завершении 0. Это также означает, что если у вас есть массив char, который не завершен нулем, вы не должны вызывать какие-либо из этих функций, поскольку он, вероятно, сделает что-то неправильно (или вы должны быть осторожны и использовать функции с буквой от их имени как strncpy).

Самая большая проблема с этим соглашением заключается в том, что существует много случаев, когда он неэффективен. Один типичный пример: вы хотите поместить что-то в конец строки с завершающим 0. Если вы сохранили размер, вы можете просто прыгать в конце строки, используя соглашение sz, вы должны проверить его char на char. Другие проблемы возникают при работе с кодированным юникодом или таковым. Но в то время, когда C был создан, это соглашение было очень простым и отлично справилось с работой.

В настоящее время буквы между двойными кавычками, такими как "строка", не являются обычными массивами char, как в прошлом, но const char *. Это означает, что указатель указывает на константу, которая не должна быть изменена (если вы хотите ее изменить, вы должны сначала ее скопировать), и это хорошо, потому что она помогает обнаруживать многие ошибки программирования во время компиляции.

Ответ 2

С++ std::string не завершены NUL.

P.S: NULL - макрос 1. NUL - \0. Не смешивайте их.

1: C.2.2.3 Макро NULL

Макрос NULL, определенный в любом из <clocale>, <cstddef>, <cstdio>, <cstdlib>, <cstring>, <ctime>, или <cwchar>, представляет собой константу нулевого указателя С++, определенную реализацией в этом Интернационале Стандарт (18.1).

Ответ 3

Конечный нуль должен прекратить строку. Без этого вам понадобится другой метод для определения его длины.

Вы можете использовать предопределенную длину:

char s[6] = {'s','t','r','i','n','g'};

Вы можете эмулировать строки в стиле pascal:

unsigned char s[7] = {6, 's','t','r','i','n','g'};

Вы можете использовать std::string (на С++). (поскольку вас не интересует std::string).

Предпочтительно использовать некоторую ранее существовавшую технологию, которая обрабатывает unicode или, по крайней мере, понимает строковое кодирование (т.е. wchar.h).

И комментарий: если вы помещаете это в программу, предназначенную для запуска на реальном компьютере, вы можете подумать о том, чтобы ввести свою собственную "строку". Это подтолкнет ваш компилятор к barf, если вы случайно попытаетесь передать его функции, ожидающей строки в стиле C.

typedef struct {
    char[10] characters;
} ThisIsNotACString;

Ответ 4

В С++ вы можете использовать класс string и вообще не иметь дело с нулевым char.

Ответ 5

Используйте std::string.

Существуют десятки других способов хранения строк, но использование библиотеки часто лучше, чем создание собственных. Я уверен, что мы могли бы придумать множество дурацких способов делать строки без нулевых терминаторов:).

Ответ 6

В C вообще не будет более легкого решения. Вы могли бы сделать то, что сделал pascal, и поместить длину строки в первый символ, но это немного больно и ограничит вашу длину строки размером целого числа, которое может поместиться в пространство первого char. В С++ я бы определенно использовал класс std::string, к которому можно получить доступ

#include <string>

Являясь широко используемой библиотекой, это почти наверняка будет более надежным, чем перенос собственного класса строк.

Ответ 7

Причина завершения NULL заключается в том, что обработчик строки может определить ее длину. Если вы не используете завершение NULL, вам нужно передать длину строк либо через отдельный параметр/переменную, либо как часть строки. В противном случае вы можете использовать другой разделитель, если он не используется внутри самой строки.

Честно говоря, я не совсем понимаю ваш вопрос, или если на самом деле это вопрос.

Ответ 8

Даже класс string сохранит его с нулевым значением. Если по какой-то причине вам абсолютно не нужен нулевой символ в конце вашей строки в памяти, вам придется вручную создать блок символов и заполнить его самостоятельно.

Я не могу лично думать о каком-либо реалистичном сценарии, почему вы хотите это сделать, поскольку нулевой символ является сигналом конца строки. Если вы также сохраняете длину строки, я думаю, вы сохранили один байт за счет того, что размер вашей переменной (вероятно, 4 байта), и получил более быстрый доступ к длине указанной строки.

Ответ 9

Просто для полноты и гвоздя это полностью.

vector<char>