Почему функция 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
Другие вопросы по тегам