【问题标题】:C File Parsing IssueC 文件解析问题
【发布时间】:2014-12-02 01:49:02
【问题描述】:

我有一个文件要读取,格式类似于

3%6%1

5%3%0

4%9%2

我需要它以某种格式保存每一行的单独字段,就像我想的那样 我可以用 SOMETHING.num1 = 3, SOMETHING.num2 = 6, SOMETHING.num3 = 1 制作 typedef SOMETHING

这是我目前所拥有的:

#define BUF 128 
#define LINES 100 

char line[LINES][BUF];

FILE *input = NULL; 
int i = 0;
int total = 0;

input = fopen("input.txt", "r");
while(fgets(line[i], BUF, input)) 
{
  /* get rid of ending \n from fgets */
  line[i][strlen(line[i]) - 1] = '\0';
  i++;
}

total = i;

printf("ORIGINAL READ:\n");

for(i = 0; i < total; ++i)
{
  printf("%s\n", line[i]);
}

printf("\nPARSED:\n");

char  *token;
char parsed[LINES][BUF];

for(i=0; i<total; i++)
{
  token = strtok(line[i], "%");

  while(token != NULL)
  {
    strcpy(parsed[i],token);
    token = strtok(NULL, "%");
  }
}

for(i=0; i<total; i++)
{
  printf("%s\n",parsed[i]);
}

问题是当我打印出解析数组中的值时,它似乎只有每行的最后一个值(即对于样本 ^,它将输出 1,0,2)。我是 C 编程新手,我该怎么做?

【问题讨论】:

  • 你为什么不直接使用scanf("%d%%%d%%%d", &amp;a, &amp;b, &amp;c)
  • 目前还不清楚您打算如何处理从 while(token != NULL) 循环中获得的每个令牌。你想用这些令牌做什么?现在,正如您所说,您正在用每个缓冲区覆盖 parsed[i] 缓冲区,因此当您用完标记时,parsed[i] 包含最后一个标记的值。
  • 关于这一行:line[i][strlen(line[i]) - 1] = '\0'; strlen() 将索引返回到字符串终止符之前的最后一个字符,因此该行应该是: line[i][strlen(line[i])] = '\0';
  • 这一行:char parsed[LINES][BUF];只为输入文件中的每一行分配一个条目。然后这一行: strcpy(parsed[i],token);一直覆盖同一行,直到文件行被完全解析。建议:1) 使用更短的 BUF,因为这些行的长度不接近 128 字节。 2) 修改 parsed[][] 的分配并修改 strcpy 行,以便在 parsed 中的每行有 3 个条目的空间,并且 strcpy 将标记放在 parsed 中的正确条目中。

标签: c file parsing


【解决方案1】:

现在您正在使用i 来索引您解析的数字,但i 也是您的行索引。您需要一个单独的索引来跟踪您已解析的数字。

int numberCount = 0;

...
    strcpy(parsed[numberCount++],token);
...

for(i=0; i<numberCount; i++)
    printf("%s\n",parsed[i]);

【讨论】:

  • 当然,这将超出已解析的数组,除非数组也更改为包含 3 倍的条目。
  • 好点。但实际上,不能保证 LINES (100) 足以满足行数,或者 LINES*3 (300) 足以满足解析数字的数量(如果一行上有 3 个以上的数字例子)。如果他在写入数组的任何地方都检查数组边界会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-23
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
相关资源
最近更新 更多