我如何读取一行,解析信息,然后将其归属于C中的结构?

时间:2017-11-02 02:33:49

标签: c arrays pointers struct

我目前正在尝试了解如何浏览C中的.txt文件,我认为我已经完成了大部分工作,但我需要做的是让人感到困惑。我需要创建一个指针数组来指向结构。 我的.txt文件中的每一行都应该包含与单个结构相对应的信息。每行应以名称开头,后跟一些浮点值。 我的问题是,当我首先使用strtok读取行并解析它们时,如何在结构中获取该信息? 那么我如何使索引i处的样本指针指向结构? 我尝试从数字中单独命名,因为数字需要他们自己的特殊atof转换,因为最初它将是一个字符串。但是我认为这可能是不正确的,因为我想要读取多行,我在while循环之前获得名称的代码只会运行一次,因此任何后续行都不会有名称分隔。我可以在技术上划分我选择的文本文件,所以也许我可以用分号和其余空格分隔名称? 如果这个问题似乎令人困惑,可能是因为我在思考

我应该声明一个结构,例如:Sample tmp; 我一直在阅读示例,但我无法弄清楚如何将信息放在一起。如果我错误地声明了我的指针数组,请告诉我...我认为我做了。我想我的话说: sample arr[SIZE] = {NULL};可能不正确,但我不确定。如果你能帮我解决所有这些背后的逻辑,我将不胜感激。感谢。

typedef struct sample{
char* name;
int list_len;
float* value_list;
}sample;



void read_and_parse(){
const int SIZE = 1024;
sample* sample = (sample*)malloc(sizeof(sample); //pointer allocation?
FILE* fin;

fin = fopen("record.txt", "r");
if (fin == NULL) {
 printf("record.txt could not be opened \n");
 exit(1);
}
else {
int i= 0;
sample arr[SIZE] = {NULL}; //here I try to make the array of pointers
char linebuf[SIZE];
token = strtok(linebuf, " "); //grab the first item




 while (fgets(linebuf, SIZE, fin) && i<SIZE) {
 arr[i] = malloc(sizeof(sample));
 arr[i.name] = token;
 token = strtok(NULL, " ");



 // now parse the linebuf and fill arr[i] with it

 i++;
}

编辑:2017年2月11日 你看到的任何打印语句都是我用于测试和识别当我最终编译此代码时正在运行的内容的愚蠢标记 这是一个更好的编辑版本的代码。我认为现在应该可以了。

typedef struct sample{
char* name;
int list_len;
float* value_list;
}sample;



void read_and_parse(FILE **fin, sample* arr[]){
 const int SIZE = 1024;

 if (*fin == NULL) {
     printf("record.txt could not be opened \n");
     exit(1);
 }
 else {
 printf("successfully opened file\n"); 


 char linebuf[SIZE];
 while ( fgets(linebuf, SIZE, fin) ) {

     arr[i] = malloc(sizeof(sample));
     int floats_per_line = 0;

     while(linebuf[i]){
        if(linebuf[i] == ' ');
        ++floats_per_line;
     }

     arr[i]->list_len = values_per_line;
     arr[i]->value_list = (float*)malloc(sizeof(float)*floats_per_line);
     arr[i]->name = strdup(strtok(linebuf, ' ')); 
     char* tok;
     int j = 0
     while(tok = strtok(NULL, ' ')){
        arr[i]->value_list[j] = atof(tok);
        ++j
     }

     i++;
    }
  }
  fclose(fin);
}

1 个答案:

答案 0 :(得分:2)

  

我如何读取一行,解析信息,然后将其归属于结构?

使用fgets()进行阅读,将文件输入的转换为字符串。 OP做得很好。然后解析字符串。

  

当我读取行并首先使用strtok解析它们时,如何(在)结构中获取该信息?
  我应该声明一个结构,例如:sample tmp;

字符串传递给辅助函数,将其解析为可以保存任何输入的sample。因此tmp的指针成员需要指向最大空间。

char name[SIZE];
char f[SIZE/2];
sample tmp = { name, 0, f };

while (i<SIZE && fgets(linebuf, SIZE, fin)) {
  if (sample_parse(&tmp, linebuf) == NULL) {
    break;  // Parsing failed for some reason, perhaps an error message?
  } 

  // Now populate arr[i] with right-sized memory allocations
  arr[i].name = strdup(tmp.name);  // ToDo: add NULL check
  arr[i].list_len = tmp.list_len;
  size_t f_size = sizeof *(tmp.value_list) * tmp.list_len;
  arr[i].value_list = malloc(f_size); // ToDo: add NULL check
  memcpy(arr[i].value_list, tmp.value_list, f_size);
  i++;
}
  

所以也许我可以用分号和其余空格分隔名称?

是。也允许其他白色空间。

  

如果我错误地声明了我的指针数组。

代码在任何地方都没有指针数组。

建议使用size_t作为数组大小类型。

typedef struct sample {
  char* name;
  // int list_len;
  size_t list_len;
  float* value_list;
} sample;

一些未经测试的解析代码。用strtok()解析该行。进一步使用strtof()解析数字标记。

#define sample_NAME_DELIMITER ":"
#define sample_NUMBER_DELIMITER " \n\t\r"

// parse for a name and then 0 or more numbers
static sample *sample_parse(sample *dest, char *linebuf) {
  char *s = strtok(linebuf, sample_NAME_DELIMITER);
  if (s == NULL) {
    return NULL;  // no name - TBD on if this is allowed
  }
  strcpy(dest->name, s);
  size_t i = 0;
  while ((s = strtok(NULL, sample_NUMBER_DELIMITER)) != NULL) {
    char *endptr;
    dest->value_list[i] = strtof(s, &endptr);
    if (s == endptr || *endptr) {
      // conversion failed or extra junk
      break;
    }
    i++;
  }
  dest->list_len = i;
  return dest;
}