Почему функция C strlen() возвращает неправильную длину символа?
Мои коды C перечислены ниже:
char s="MIDSH"[3];
printf("%d\n",strlen(&s));
Результат выполнения равен 2, что неверно, поскольку char s это просто 'S'.
Кто-нибудь знает, почему и как решить эту проблему?
5 ответов
Это на самом деле довольно интересный вопрос. Давайте разберемся с этим:
"MIDSH"[3]
Строковые литералы имеют типы массивов. Таким образом, приведенное выше применяет оператор индекса к массиву и вычисляет до 4-го символа 'S'. Затем он присваивает его односимвольной переменной s
,
printf("%d\n",strlen(&s));
поскольку s
является одним символом, а не частью реальной строки, поведение не определено для приведенного выше кода.
Подпись strlen
является:
size_t strlen(const char *s);
/* The strlen() function calculates the
length of the string s, excluding the
terminating null byte ('\0'). */
strlen
ожидает ввода const char array
теряет силу Но когда вы передаете адрес auto
переменная, вы не можете гарантировать это, и, следовательно, ваша программа имеет неопределенное поведение.
Кто-нибудь знает, почему и как решить эту проблему?
sizeof(char)
гарантированно будет 1
, Так что используйте sizeof
или же 1
,
Заявление
printf("%d\n",strlen(&s));
не имеет смысла для данного случая. strlen
ожидает нулевую завершающую строку, s
имеет char
тип и &s
не обязательно указывать на строку. То, что вы получаете, является результатом неопределенного поведения программы.
Чтобы получить размер s
ты можешь использовать sizeof
оператор
printf("%zu\n", sizeof(s));
strlen
функция обрабатывает свой аргумент как указатель на последовательность символов, где последовательность заканчивается '\0'
персонаж.
Передав указатель на односимвольную переменную s
Вы эффективно говорите, что &s
это первый символ в такой последовательности, но это не так. Это означает strlen
продолжит поиск в памяти при ложных посылках, и у вас будет неопределенное поведение.
Когда вы используете "char s=", вы создаете новый адрес в стеке для 's', и этот адрес не может быть добавлен или уменьшен! поэтому вы предоставляете strlen символ *, но он не может найти '\0' по добавлению адреса. Все неправильно. Вы должны использовать strlen с адресом для char, который является массивом.
char* s = "MIDSH";
printf("%d\n", strlen(s)); //print 5
s++;
printf("%d\n", strlen(s)); //print 4