В C, если у меня есть:
char *reg = "[R5]";
и я хочу
char *reg_alt = "R5"
(равный одному и тому же, но без скобок), как это сделать?
Я пробовал
*char reg_alt = reg[1:2];
но это не работает.
В C, если у меня есть:
char *reg = "[R5]";
и я хочу
char *reg_alt = "R5"
(равный одному и тому же, но без скобок), как это сделать?
Я пробовал
*char reg_alt = reg[1:2];
но это не работает.
Нет встроенного синтаксиса для работы с подобными подстроками, поэтому вам нужно скопировать содержимое вручную:
char res[3];
memcpy(res, ®[1], 2);
res[2] = '\0';
Я предлагаю вам прочитать основной текст на языке C, а не считать, что методы с других языков будут работать.
Во-первых, char *reg = "[R5]";
не является строкой. Это указатель, который инициализируется, чтобы указать (то есть его значение является адресом) первого символа строкового литерала ("[R5]"
).
Во-вторых, reg_alt
также является указателем, а не строкой. Присвоение ему будет содержать адрес чего-то. Строки не являются гражданами первого класса в C, поэтому оператор присваивания не работает с ними.
В-третьих, 1:2
не указывает диапазон - это действительно более недействительный синтаксис. Да, я знаю, что другие языки. Но не C. Следовательно, мой комментарий, который вы не можете принять, C позволит вещам так, как это делают другие языки.
Если вы хотите получить подстроку из другой строки, существуют различные способы. Например:
char substring[3];
const char *reg = "[R5]"; /* const since the string literal should not be modified */
strncpy(substring, ®[1], 2); /* copy 2 characters, starting at reg[1], to substring */
substring[2] = '\0'; /* terminate substring */
printf("%s\n", substring);
strncpy()
объявляется в стандартном заголовке <string.h>
. Требуется прекращение подстроки, так как формат printf()
%s
ищет нулевой символ, чтобы отметить конец.
При использовании строк с нулевым завершением (по умолчанию в C) вы действительно можете дешево создать подстроку другой строки, просто изменив указатель начального символа, но вы не можете заставить новую подстроку иметь другой нулевой ограничитель.
Опция заключается в использовании библиотеки строк Pascal. Паскальные строки имеют префикс длины вместо C-строк, которые заканчиваются на нуль, что означает, что строки Pascal могут совместно использовать содержимое большего строкового буфера, а генерация подстроки дешевая (O(1)
-cheap). Строка Pascal выглядит так:
struct PString {
size_t length;
char* start;
}
PString substring(const PString* source, size_t offset, size_t length) {
// Using C99 Designated Initializer syntax:
return PString { .length = length, .start = source.start + offset };
}
Недостатком является то, что большинство библиотек библиотеки C и платформ используют строки с нулевым символом, и если ваша строка Pascal не заканчивается нулевым символом, вам нужно будет скопировать подстроку в новый буфер (в O(n)
время).
Конечно, если вы чувствуете себя опасно (и используете изменяемые буферы символов), вы можете взломать его, чтобы временно вставить нулевой терминатор, например:
struct CStr {
char* start;
char* end;
char temp;
}
CStr getCStr(PString* source) {
char* terminator = (source.start + source.length);
char previous = *terminator;
*terminator = '\0';
return CStr { .start = source.start, .end = terminator, .temp = previous };
}
void undoGetCStr(CStr cstr) {
*cstr.end = cstr.temp;
}
Используется так:
PString somePascalString = doSomethingWithPascalStrings();
CStr temp = getCStr( somePascalString );
printf("My Pascal string: %s", temp.start ); // using a function that expects a C-string
undoGetCStr( temp );
..., который затем дает вам производительность O(1)
PString-to-CString, если вы не заботитесь о безопасности потоков.
Нужно быть char?
Потому что это работает только тогда, когда это "строка", Так что, возможно, вам это нужно
char reg[] = "[R5]";
Тогда вы можете сделать другое дело или просто разделите строку следующим образом question