簡體   English   中英

從帶有 strtok + qsort 問題的行中讀取

[英]Reading from lines with strtok + qsort problem

我想要創建的是一個從{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 function 未正確訂購數據。 它根本沒有訂購。 output 與訂購前相同。

我能做些什么? 謝謝你。 如果需要更多詳細信息,請告訴我,我會確保將其發布。

問題是

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

你想為 n 個元素保留空間,而不是為 n 個指向元素的指針,切換到

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

此外,始終使用帶有realloc的臨時變量

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM