Ошибка с strlen? - PullRequest
       22

Ошибка с strlen?

0 голосов
/ 30 ноября 2018

Я только начал работать с C, и я только начал пытаться выяснить вызов по ссылке в функциях.Я заметил странный результат в моем выводе при использовании strlen () для перебора строки и изменения ее содержимого.В этом примере результат strlen () равен 3, не включая нулевой символ, но если я не проверю явно нулевой символ (или использую меньше, чем результат strlen () вместо меньше или равно) во время forцикл, то он дает странный битовый символ в выводе, который я предполагаю из-за нулевого символа?

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

Код:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void f_test_s(char s[]);
void f_test_s2(char s[]);

int main(){
    char s_test[] = "abc";

    f_test_s(s_test);
    f_test_s2(s_test);

    puts("\nTest complete!");

    return 0;
}


void f_test_s(char s[]){

    puts("Test #1: ");
    printf("string before: %s\n", s);

    int len = strlen(s);
    printf("strlen() = %d\n", len); 
    int i=0;             
    for(i=0;i<=len;i++){
        if(s[i] != '\0'){
            s[i]++;
        }
    }

    printf("string after: %s\n", s);

}


void f_test_s2(char s[]){

    puts("\nTest #2: ");
    printf("string before: %s\n", s);

    int len = strlen(s);
    printf("strlen() = %d\n", len);
    int i=0;         
    for(i=0;i<=len;i++){
        s[i]++;
    }

    printf("string after: %s\n", s);

} 

output:

Test #1: 
string before: abc
strlen() = 3
string after: bcd

Test #2: 
string before: bcd
strlen() = 3
string after: cde

Test complete!

Если это имеет значение, то яиспользуя gcc версии 7.3.0 в Ubuntu.Я определенно не эксперт ни в C, ни в gcc, ни в Ubuntu.

Ответы [ 2 ]

0 голосов
/ 30 ноября 2018

Измените это:

for (i = 0; i <= len; i++) {

на это:

for (i = 0; i < len; i++) {

, поскольку strlen() возвращает длину строки.Строка AC равна числу символов между началом строки и завершающим нулевым символом ( без учета самого завершающего нулевого символа ).

Ваш код вызывает неопределенное поведение (UB)), так как вы выходите за пределы.Стандартные строковые функции (например, printf()) зависят от завершающего символа NULL для обозначения конца строки.Без этого они не знают, когда остановиться.,.

0 голосов
/ 30 ноября 2018

Это проблема:

for (i = 0; i <= len; i++) {
    s[i]++;
}

Должно быть:

for (i = 0; i < len; i++) {
    s[i]++;
}

s[len] - нулевой символ (0).Когда вы удалили null char и заменили его значением 1, содержимое массива теперь равно {'a', 'b', 'c', 0x1}.И когда printf пытается напечатать s, он будет продолжать печатать символы после адреса памяти значения массива, пока не встретит нулевой символ.Технически это неопределенное поведение.

...