【问题标题】:Reading from lines with strtok + qsort problem从带有 strtok + qsort 问题的行中读取
【发布时间】:2021-04-28 00:45:06
【问题描述】:

我想要创建一个程序,该程序从{key: value} 形式的外部文件中获取行。例如,我们有文件t.dat

{myName: Mario}
{name2: Asdadas}
{someOtherData: _D123}

我的程序应该根据key(在我们的例子中,myNamename2someOtherData)的长度以及如果两个具有相同长度的键是找到后,它们应该根据value 进行字典排序。

我通过使用struct array 来做到这一点,它将保留文档中每一行的数据:

typedef struct Line{
    char key[50];
    char value[50];
}Line;

并尝试使用fgets(取每一行)和strtok从文件中取出该数据。

这是我的全部代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 512

typedef struct Line{
    char key[50];
    char value[50];
}Line;

int comp(const void* a, const void* b)
{
    const Line *aa = a;
    const Line *bb = b;
    puts(bb->key);
    if (strlen(aa->key) == strlen(bb->key)) {
        return strcmp(aa->key, bb->key);
    }
    return  strlen(bb->value)-strlen(aa->value);
}

int main(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Invalid number of args.\n");
        return -1;
    }
    FILE *f = fopen(argv[1], "rb");
    if (!f)
    {
        printf("Unable to open the specified file.\n");
        return -2;
    }
    
    Line* ln;

    char buff[MAX];
    int lineNumber = 0;
    int isSet = 0;
    int i = 0;
    while (fgets(buff, MAX, f))
    {
        char *p = strtok(buff, " {}:\n\r\t");
        while (p)
        {
            char word[MAX] = "";
            if (isSet == 0)
            {
                ln = malloc(1*sizeof(ln));
                isSet = 1;
            }
            else if (i == 0) ln = (Line*)realloc(ln, (lineNumber+1)*sizeof(ln));
            word[0] = '\0';
            if (i == 0) {
                strcpy(word, p);
                strcpy(ln[lineNumber].key, word);
                i = 1;
            }
            else if (i == 1) {
                strcpy(word, p);
                strcpy(ln[lineNumber].value, word);
                lineNumber++;
                i = 0;
            }
            p = strtok(NULL, " {}:\n\r\t");
        }

    }

    qsort(ln, lineNumber, sizeof(ln), comp);
    puts("\n");
    for (int i = 0; i<lineNumber; i++)
    {
        printf("%s\n", ln[i].key);
    }
    return 0;
}

问题是,第一行的数据没有正确读取(我指的是value - "Mario"。它包含来自key 的元素,但肯定不是单词Mario) .以为这可能来自strtok,但没有找到解决方案。

此外,使用提供的comp 函数未正确排序数据。它根本没有订购。输出和下单前一样。

我能做什么?谢谢你。如果需要更多详细信息,请告诉我,我会确保发布。

【问题讨论】:

    标签: c file realloc strtok qsort


    【解决方案1】:

    问题是

    ln = (Line*)realloc(ln, (lineNumber+1)*sizeof(ln));
    

    你想为n个元素保留空间,而不是n个指向元素的指针,切换到

    ln = realloc(ln, (lineNumber+1)*sizeof(*ln)); // Don't cast
    

    另外,always use a temporary variablerealloc

    Line *temp = realloc(ln, (lineNumber+1)*sizeof(*ln));
    
    if (temp == NULL)
    {
        // raise error
    }
    ln = temp;
    

    这里也一样

    qsort(ln, lineNumber, sizeof(ln), comp);
    

    每个元素占用sizeof(*ln),而不是sizeof(ln),切换到

    qsort(ln, lineNumber, sizeof(*ln), comp);
    

    【讨论】:

    • 修改了代码,但是行还是无序的
    • 是的,qsort 也使用了错误的尺寸,您需要进行修改。
    • 另外,将您的回复标记为答案。上帝保佑你!!!
    猜你喜欢
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多