c - 如何读取文本文件中的逗号分隔行并将其字段插入到结构指针数组中?

标签 c arrays pointers struct strtok

一段时间以来,我一直在努力弄清楚这个问题,我觉得我必须接近了。基本上,我有一个数据文件,其中包含由换行符分隔的各个国家/地区的记录。每条记录都包含逗号分隔的字段,我正在尝试从中提取某些字段。

例如(单行):

60,AFG,Afghanistan,Asia,Southern and Central Asia,652090,1919,22720000,45.9,5976,Afganistan/Afqanestan,Islamic Emirate,Mohammad Omar,1,AF

这些行中的每一行都将构成一个结构。本质上,我想读取每一行并将其插入到一个结构指针数组中(如此动态地)。我也只想要特定的领域。当我“标记化”该行时,我想要代码、姓名、人口和预期生命周期的字段。分别是:

AFG,阿富汗,22720000,45。

我的想法是使用 fgets() 读取文件中的每一行,并在一个循环中 malloc() 一些内存用于指针,标记我想要的字段,然后插入。但是,我正在做的事情一定是错误的,因为各种测试似乎没有在我的输出中显示任何内容。

这是我到目前为止的工作。我将不胜感激任何帮助。

#include "allheaders.h" // contains all common headers for personal use

#define BUF_SIZE 512
#define NUM_RECS 238

typedef struct {
   char code[4];
   char name[40];
   int population;
   float lifeExpectancy;
} Country;

typedef Country *countryPtr;

int main( int argc, const char* argv[] ) {

/* Opening the file */
FILE *filePtr;  // pointer to file
if ((filePtr = fopen("AllCountries.dat", "r")) == NULL) {   // if couldn't open file
    printf("Error opening file\n"); // error message
    exit(1);
}

/* Reading the file */
char buffer[BUF_SIZE];  // buffer to read
int index = 0;
char *token;
countryPtr *myCountries = malloc(sizeof(*myCountries) * NUM_RECS);
for(int i = 0; i < NUM_RECS; ++i) {
    myCountries[i] = malloc(sizeof(*myCountries[i]));
}

while (fgets(buffer, BUF_SIZE, filePtr) != NULL) {

    token = strtok(buffer,",");
    token = strtok(NULL, ",");
    strcpy(myCountries[index]->code, token);
    token = strtok(NULL, ",");
    strcpy(myCountries[index]->name, token);
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");
    myCountries[index]->population = atoi(token);
    token = strtok(NULL, ",");
    myCountries[index]->lifeExpectancy = atof(token);
    //printf("%s", buffer);
    index++;
}

printf("%s", myCountries[1]->code); // test?
free(myCountries);

最佳答案

请看下面的内容。 首先,您需要做一些工作来改进标记为 NYI 的区域

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

#define BUF_SIZE 512
#define NUM_RECS 238

typedef struct {
  char code[4]; // NYI - magic numbers
  char name[41]; // NYI - magic numbers
  int population; // NYI - what if atoi fails? 
  float lifeExpectancy; // NYI - what if atof fails?
} Country;

typedef Country* countryPtr;

int main( int argc, const char* argv[] ) {
  /* Opening the file */
  FILE *filePtr;  // pointer to file
  if ((filePtr = fopen("a.txt", "r")) == NULL) {   // if couldn't open file
    printf("Error opening file\n"); // error message
    exit(1);
  }

  /* Reading the file */
  char buffer[BUF_SIZE];  // buffer to read
  int index=0;
  char *token; // NYI - initial value
  countryPtr* myCountries = calloc(NUM_RECS, sizeof(countryPtr));
  for(int i = 0; i < NUM_RECS; ++i) {
    myCountries[i] = calloc(1, sizeof(Country));
  }

  while (fgets(buffer, BUF_SIZE, filePtr) != NULL) {
    // NYI - magic lengths / overflow strcpy targets

    token = strtok(buffer,","); // NYI - This is probably not the best way to do this. At least fold into a loop.
    token = strtok(NULL, ",");
    strcpy(myCountries[index]->code, token);
    token = strtok(NULL, ",");
    strcpy(myCountries[index]->name, token);
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");
    token = strtok(NULL, ",");

    myCountries[index]->population = atoi(token); // NYI - atoi failure
    token = strtok(NULL, ",");
    myCountries[index]->lifeExpectancy = atof(token); // NYI - atof failure
    printf("%s", buffer);
    index++;
  }

  printf("%s\n", myCountries[0]->code); // test? NYI - need more proof
  free(myCountries); // NYI - this is a sequence - need to free each of the new elements 
}

关于c - 如何读取文本文件中的逗号分隔行并将其字段插入到结构指针数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41949376/

相关文章:

字符指针段错误

c++ - 带/不带指针的函数原型(prototype)使用区别

c - 当您将学生人数的值输入为 3 时,这个 while 循环如何打印 3 作为 cnt 的值而不是 2?

c - syscall 是 x86_64 上的指令吗?

有人能解释一下这个C程序的输出吗?

c - 在链表中插入元素到列表中最大元素之后

c - 如何获取以 '+' 字符开头的选项的值?

java - 无法将 double 型格式化为在小数点分隔符后打印 2 位数字

java - 如何将 java 对象转换为它自己的 getComponentType?

ruby - 正则表达式根据模式在 Ruby 中拆分数组