简体   繁体   English

我丢失了结构(c)中的值

[英]I lose the values in a struct (c)

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

#define stock_dir "/Users/myname/prices/"
#define file_list "/Users/myname/trade/trade/nasdaq100_stock_list.txt"
#define look_back_period 3
#define num_stocks 103
#define days_of_data 21

int main()
{
    FILE *stocks, *stk;
    char stock[11], fullpath[50] = "\0", header[25];
    char line_of_data[40];
    char *sclose, *svol;
    int n = 0, i = 0;
    typedef struct daily_data {
        char  *date;
        float close;
        int vol;
    }data;
    
    sclose = (char*) malloc(20*sizeof(char));
    svol =  (char*) malloc(20*sizeof(char));
    
    data** day_data = (data**) malloc(num_stocks*sizeof(data*)  );
   
    if (day_data == NULL)
        {
        printf("day_data not allocated\n");
        exit(0);
        }

    for(i = 0; i < num_stocks; i++)
        if ((day_data[i] = (data*)malloc(days_of_data*sizeof(data))) == NULL)
        {
        printf("data[%d] not allocated\n", i);
        exit(0);
        }

    for(i = 0; i < num_stocks; i++)
      for(n = 0; n < days_of_data; n++)
       
          if ((day_data[i][n].date = (char*)malloc(20)) == NULL)
          {  printf("data[%d][%d] not allocated\n", i,n);
             exit(0);
          }

    /* ... code omitted ... */

    if ( (stocks = fopen(file_list, "r") )== NULL)
        printf("didn't open file list\n");
    i = 0;
 
    while (fgets(stock, sizeof(stock), stocks) != NULL)
    {
       printf("%s",stock);
       strcpy(fullpath,stock_dir);
        strcat(fullpath,stock);
        fullpath[strcspn(fullpath, "\n")] = 0;
        if ( (stk = fopen(fullpath, "r") )== NULL)
               printf("didn't open quote list\n");
        fgets(header,sizeof(header),stk);
        n=0;
        while(fgets(line_of_data, sizeof(line_of_data),stk) !=NULL)
            {
                fgets(line_of_data,sizeof(line_of_data),stk);
                day_data[i][n].date = strtok(line_of_data, ",");
                sclose = strtok(NULL,",");
                day_data[i][n].close = atof(sclose);
                svol = strtok(NULL, ",");
                day_data[i][n].vol = atoi(svol);;
                printf("%s %f %d\n",day_data[i][n].date,day_data[i][n].close,day_data[i][n].vol);
              n++;
            }
    
        fclose(stk);
        i++;
    }
             
   for (n = look_back_period - 1; n  < (days_of_data  - look_back_period); n++)
      printf("%d %s  %f %d\n",n, day_data[1][n].date, day_data[1][n].close, day_data[1][n].vol);
    
}

The print statement in the while(fgets(line_of_data, sizeof(line_of_data),stk) !=NULL) loop shows that everything went into the right place. while(fgets(line_of_data, sizeof(line_of_data),stk) !=NULL)循环中的打印语句表明一切都进入了正确的位置。 But when I print values outside they're mostly wrong.但是当我在外面打印值时,它们大多是错误的。 I'm supposed to add more details but I don't know what else to say.我应该添加更多细节,但我不知道还能说什么。 I lose the values in the struct when I leave the loop.当我离开循环时,我会丢失结构中的值。

You overwrite the same data again and again.您一次又一次地覆盖相同的数据。

Take a look at your structure:看看你的结构:

    typedef struct daily_data {
        char  *date;  ///< a pointer without own storage
        float close;
        int vol;
    }data;

while processing your file you read each line into line_of_data在处理您的文件时,您将每一行读入line_of_data

while(fgets(line_of_data, sizeof(line_of_data),stk) !=NULL)

you tokenize the line_data and assign the pointer to data->date您标记line_data并将指针分配给data->date

day_data[i][n].date = strtok(line_of_data, ",");

What tokenize ( strtok reference ) does is inserting terminators into your input string and returning the pointer to the start of the new part of your input. tokenize ( strtok reference ) 所做的是将终止符插入到输入字符串中,并将指针返回到输入新部分的开头。 So no new memory is allocated at this point.所以此时没有分配新的 memory。 the returned pointer points into your input string.返回的指针指向您的输入字符串。

So effectively you assigning the local variable pointer to your data storage structure.如此有效地将局部变量指针分配给数据存储结构。

Additionally to this you lose the pointer to your initially allocated memory for the date pointer.除此之外,您丢失了指向您最初分配的 memory date指针的指针。

I would suggest you to remove the a priory allocation of date and allocate the required memory at the point you really know the required length or if you are sure, you know the maximum length, then you can just make the date member an array.我建议您删除date的先验分配,并在您真正知道所需长度时分配所需的 memory,或者如果您确定知道最大长度,则可以将date成员设为数组。

So you either have to allocate new memory and copy the tokenized data or if you made date a fixed size array, just copy the tokenized data.因此,您要么必须分配新的 memory 并复制标记化数据,要么如果您将date设置为固定大小的数组,只需复制标记化数据。

on the first variant it would look like this在第一个变体上,它看起来像这样

  char * tok = strtok(line_of_data, ",");
  day_data[i][n].date = malloc(strlen(tok)+1);
  strcpy(day_data[i][n].date, tok); 

(+ remove the pre allocation of the date member) (+去掉date成员的预分配)

or the second variant:或第二个变体:

change data todata更改为

    typedef struct daily_data {
        char  date[20];
        float close;
        int vol;
    }data;

and the processing code looks like this:处理代码如下所示:

  char * tok = strtok(line_of_data, ",");
  strcpy(day_data[i][n].date, tok); 

(+ (of course) remove the pre allocation of the date member) (+(当然)去掉date成员的预分配)

You also should in any case add error handling if the tokenized string exceeds the max length or the format of the lines does not match the expectation (missing delimiters, wrong/invalid number(formats), ...).如果标记化的字符串超过最大长度或行的格式与预期不匹配(缺少分隔符、错误/无效的数字(格式)......),您还应该在任何情况下添加错误处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM