Strcmp не будет возвращать ноль для одних и тех же двух строк

Я читаю файл CSV, используя fscanf, который имеет два поля.

datatype_t*read(FILE* fp)
{
 char name[66];
 char data[1466];
 if (fscanf(fp, "%[^,] %[^\n]", name, data) == 2) {
    datatype_t *d = (datatype_t*)malloc(sizeof(datatype_t));
    d->name = strdup(name);
    d->data = strdup(data);
return d;
}
return NULL;
}

Данные файла CSV выглядят следующим образом:

Мистер Дэйв, школьный учитель
Майк, руководитель
Сачин, сотрудник

Теперь я читаю другой текстовый файл, в котором есть данные.

char buffer[66];
    if (fgets(buffer,sizeof buffer, fp) != NULL ) {
        keydata_t *k = (keydata_t*)malloc(sizeof(keydata_t));
        size_t len = strlen(buffer);
    if(buffer > 0 &&  buffer[len-1] == '\n'){
        buffer[--len] = '\0';
}
k->name = strdup(buffer);
return k;
}
return NULL;
}

Данные txt файла выглядят так.
Мистер Дэйв
Рон
Мистер Тим

Теперь, когда я сравниваю строки данных:

new_ptr = root; 
while((keyt = read_key(keyfile))!= NULL){

    printf("%s\n", keyt->name);
    printf("%s\n", root->key);
    if(strcmp(keyt->name, root->key) == 0){
        printf("match\n");
    }
    else if(strcmp(keyt->name, root->key) > 0){
        printf("not equal\n");
    }
    else if (strcmp(keyt->name, root->key) < 0){
        printf("not equal\n");
    }
    new_ptr = search(new_ptr, keyt);
}

Он продолжает печатать
не равно
даже для мистера Дейва, где должно быть совпадение. Я не могу понять проблему с двумя.


person Dave    schedule 13.09.2016    source источник
comment
Вы отладили свой код? Или, по крайней мере, вы распечатали то, что прочитала программа?   -  person GMichael    schedule 13.09.2016
comment
@GMichael: Да, он правильно печатает имена, но говорит, что они не равны, когда он проходит через strcmp!   -  person Dave    schedule 13.09.2016
comment
эта строка: if (fscanf(fp, "%[^,] %[^\n]", name, data) == 2) { будет включать команду , в качестве первого символа второго параметра. предложить: if (fscanf(fp, "%[^,] %c %[^\n]", name, data) == 2) {   -  person user3629249    schedule 15.09.2016
comment
в C возвращаемый тип из функций выделения памяти: (malloc, calloc, realloc) — это void*, который может быть назначен любому другому указателю. приведение возвращаемого типа просто загромождает код и затрудняет его понимание, отладку и поддержку. Предложите снять гипс. Всегда проверяйте (!=NULL) возвращаемое значение перед его использованием, чтобы убедиться, что операция прошла успешно.   -  person user3629249    schedule 15.09.2016
comment
имена переменных должны указывать содержание или использование (или, лучше, и то, и другое) d бессмысленно, даже в текущем опубликованном коде.   -  person user3629249    schedule 15.09.2016
comment
для простоты понимания и удобочитаемости 1) последовательно делать отступы в коде. отступ после каждой открывающей скобки '{'. убрать отступ перед каждой закрывающей фигурной скобкой '}'. 2) использовать (постоянное) горизонтальное и вертикальное расстояние   -  person user3629249    schedule 15.09.2016
comment
что это должно означать: if(buffer > 0 && buffer[len-1] == '\n'){ выражение buffer > 0 ВСЕГДА будет истинным, потому что в C ссылка на имя массива ухудшается до адреса первого байта массива. Возможно, вы имели в виду: if( len > 0 && buffer[len-1] == '\n'){   -  person user3629249    schedule 15.09.2016


Ответы (2)


Прежде всего, вы должны напечатать каждый символ строк, которые вы хотите сравнить, как значения hex/dec. Возможно, строки содержат символы, которые печатаются в консоли, но вы их не видите. Видимый вывод может выглядеть одинаково, но все же может отличаться. Печать (например) шестнадцатеричных значений точно покажет вам, что находится внутри строк.

Затем, если вывод будет одинаковым для обеих строк, а strcmp все равно вернет что-то отличное от 0, вам следует беспокоиться (но я уверен, что этого не будет :)

person gravell    schedule 13.09.2016

person    schedule
comment
Даже если это новая строка, она будет распечатана, когда я попытаюсь отладить ее, поставив оператор печати. Он печатал только имя, и после каждого имени не печаталась новая строка. - person Dave; 13.09.2016
comment
Когда он возвращается в основной, я проверил, что он печатает, и он печатает только имя. Что-то вроде этого printf(%s %s\n,keyt-›name, root-›key); Он вывел Mr Dave Mr Dave Тем не менее, он не говорит о совпадении, когда сравнивает строки - person Dave; 13.09.2016
comment
В формате printf есть \n. Попробуйте напечатать, используя что-то вроде ==%s==\n, чтобы увидеть, не встроено ли что-нибудь в строку. Еще лучше печатать побайтно в шестнадцатеричной форме. - person GMichael; 13.09.2016
comment
Поэтому, когда я распечатал, используя ==%s==\n, например (printf(==%s==\n, keyt-›name);), по какой-то причине он вывел Mr Tim ==e. - person Dave; 13.09.2016
comment
Пробовали это? if(strcmp(keyt-›name && root-›key) == 0) - person Technologeek; 13.09.2016
comment
@Technologeek: Да, слишком мало аргументов для ошибки вызова функции. - person Dave; 13.09.2016