【发布时间】:2021-04-28 00:45:06
【问题描述】:
我想要创建一个程序,该程序从{key: value} 形式的外部文件中获取行。例如,我们有文件t.dat:
{myName: Mario}
{name2: Asdadas}
{someOtherData: _D123}
我的程序应该根据key(在我们的例子中,myName、name2 或someOtherData)的长度以及如果两个具有相同长度的键是找到后,它们应该根据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