【问题标题】:Strcmp wont return zero for same two same stringsstrcmp 不会为相同的两个相同的字符串返回零
【发布时间】:2016-09-13 04:35:38
【问题描述】:

我正在使用具有两个字段的 fscanf 读取 CSV 文件。

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);
}

一直打印
不等于
即使对于应该匹配的戴夫先生。我似乎无法弄清楚这两个问题。

【问题讨论】:

  • 你调试过你的代码吗?或者至少,你打印了程序读取的内容吗?
  • @GMichael :是的,它正确打印出名称,但它说通过 strcmp 时它们不相等!
  • 这一行:if (fscanf(fp, "%[^,] %[^\n]", name, data) == 2) { 将包含命令, 作为第二个参数的第一个字符。建议:if (fscanf(fp, "%[^,] %c %[^\n]", name, data) == 2) {
  • 在 C 中,内存分配函数的返回类型:(malloc, calloc, realloc) 是void*,可以分配给任何其他指针。转换返回的类型只会使代码混乱,使其更难以理解、调试和维护。建议去掉演员表。使用前务必检查 (!=NULL) 返回值,以确保操作成功。
  • 变量名应该表示内容或用法(或者更好,两者兼有)d 是没有意义的,即使在当前发布的代码中也是如此。

标签: c csv fgets scanf strcmp


【解决方案1】:

来自man fgets

fgets 从流中最多读入一个小于 size 的字符并将它们存储到 s 指向的缓冲区中。在 EOF 或换行符后停止读取。如果读取了换行符,则将其存储到缓冲区中。一个终止的空字节(aq\0aq)存储在缓冲区中的最后一个字符之后。

fscanf 将换行符存储在缓冲区中。

请尝试检查keyt-&gt;name 的最后一个符号是什么,如果是换行符则将其删除

【讨论】:

  • 即使它是换行符,当我尝试通过放置 print 语句对其进行调试时,它也会打印出来。它只打印了名称,每个名称后没有打印新行
  • 当它返回 main 时,我测试了它打印的内容,它只打印名称。像这样 printf("%s %s\n",keyt->name, root->key);它输出了 Mr Dave Mr Dave 然而它在字符串比较时没有说匹配
  • printf 的格式中有\n。尝试使用==%s==\n 之类的内容进行打印,以查看字符串中是否嵌入了任何内容。更好的是,以十六进制形式逐字节打印。
  • 所以当我使用 ==%s==\n 打印出来时,例如 (printf("==%s==\n", keyt->name);) 它输出 Mr Tim = =e 出于某种原因。
  • 试过这个吗? if(strcmp(keyt->name && root->key) == 0)
【解决方案2】:

首先,您应该将要比较的字符串的每个字符打印为十六进制/十进制值。字符串可能包含在控制台中打印但您看不到它们的字符。可见输出可能看起来相同,但仍可能不同。打印(例如)十六进制值将准确显示字符串内部的内容。

如果两个字符串的输出相同,并且 strcmp 仍会返回 0 以外的值,你应该担心(但我相信它不会是 :)

【讨论】:

    猜你喜欢
    • 2016-01-10
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多