Определение длины строкового литерала
Учитывая массив указателей на строковые литералы:
char *textMessages[] = {
"Small text message",
"Slightly larger text message",
"A really large text message that "
"is spread over multiple lines"
}
Как определить длину конкретного строкового литерала - скажем, третьего? Я попытался использовать команду sizeof следующим образом:
int size = sizeof(textMessages[2]);
Но результатом является количество указателей в массиве, а не длина строкового литерала.
Ответы
Ответ 1
Если вы хотите, чтобы число, вычисленное во время компиляции (в отличие от во время выполнения с strlen
), вполне нормально использовать выражение типа
sizeof "A really large text message that "
"is spread over multiple lines";
Возможно, вы захотите использовать макрос, чтобы избежать повторения длинного литерала:
#define LONGLITERAL "A really large text message that " \
"is spread over multiple lines"
Обратите внимание, что значение, возвращаемое sizeof
, включает в себя завершающий NUL, так что это больше, чем strlen
.
Ответ 2
Мое предложение состояло в том, чтобы использовать strlen и включить оптимизацию компилятора.
Например, с gcc 4.7 на x86:
#include <string.h>
static const char *textMessages[3] = {
"Small text message",
"Slightly larger text message",
"A really large text message that "
"is spread over multiple lines"
};
size_t longmessagelen(void)
{
return strlen(textMessages[2]);
}
После запуска make CFLAGS="-ggdb -O3" example.o
:
$ gdb example.o
(gdb) disassemble longmessagelen
0x00000000 <+0>: mov $0x3e,%eax
0x00000005 <+5>: ret
т.е. компилятор заменил вызов на strlen
постоянным значением 0x3e = 62.
Не тратьте время на выполнение оптимизаций, которые компилятор может сделать для вас!
Ответ 3
strlen
может быть?
size_t size = strlen(textMessages[2]);
Ответ 4
Вы должны использовать метод библиотеки strlen()
для получения длины строки. sizeof
даст вам размер textMessages[2]
, указатель, который будет зависящим от машины (4 байта или 8 байтов).
Ответ 5
strlen дает длину строки, тогда как sizeof возвращает размер Тип данных в байтах, которые вы ввели как параметр.
strlen
sizeof
Ответ 6
Вы можете использовать тот факт, что значения в массиве последовательны:
const char *messages[] = {
"footer",
"barter",
"banger"
};
size_t sizeOfMessage1 = (messages[1] - messages[0]) / sizeof(char); // 7 (6 chars + '\0')
Размер определяется с помощью границ элементов. Пространство между началом первого и началом второго элемента является размером первого.
Это включает завершение \0
. Решение, конечно, работает только с постоянными строками. Если бы строки были указателями, вы бы указали размер указателя вместо длины строки.
Не гарантируется работа. Если поля выровнены, это может привести к неправильным размерам, и могут возникнуть другие оговорки, введенные компилятором, например, слияние идентичных строк.
Также вам понадобится как минимум два элемента в вашем массиве.
Ответ 7
Я расскажу вам кое-что, согласно моим массивам Knowledge указатели - это то же самое кроме, когда вы используете sizeof
.
Когда вы используете sizeof
в указателе, он всегда будет всегда 4 BYTE, независимо от того, на что указывает указатель, но если он используется в массиве, он вернет . большой в байтах?.
В вашем примере здесь *textMessage[]
является массивом указателя, поэтому, когда вы используете sizeof(textMessage[2])
, он вернет 4 BYTE, потому что textMessage[2]
является указателем.
Я надеюсь, что это будет полезно для вас.