Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何为结构动态赋值_C_Struct_Token_Dynamic Memory Allocation_Strtok - Fatal编程技术网

C 如何为结构动态赋值

C 如何为结构动态赋值,c,struct,token,dynamic-memory-allocation,strtok,C,Struct,Token,Dynamic Memory Allocation,Strtok,我很难理解如何访问和更改结构的值。该程序接收一些外部文件并对每个字符串进行标记,并将它们分类到以下气候信息字段中。外部文件如下所示: TDV格式: TN 1424325600000 dn20t1kz0xrz 67.0 0.0 0.0 0.0 101872.0 262.5665 TN 1422770400000 dn2dcstxsf5b 23.0 0.0 100.0 0.0 100576.0 277.808

我很难理解如何访问和更改结构的值。该程序接收一些外部文件并对每个字符串进行标记,并将它们分类到以下气候信息字段中。外部文件如下所示:

TDV格式:

 TN     1424325600000   dn20t1kz0xrz    67.0    0.0  0.0     0.0    101872.0    262.5665
 TN     1422770400000   dn2dcstxsf5b    23.0    0.0  100.0   0.0    100576.0    277.8087
 TN     1422792000000   dn2sdp6pbb5b    96.0    0.0  100.0   0.0    100117.0    278.49207
 TN     1422748800000   dn2fjteh8e80    6.0     0.0  100.0   0.0    100661.0    278.28485
 TN     1423396800000   dn2k0y7ffcup    14.0    0.0  100.0   0.0    100176.0    282.02142
列的顺序如下:第一列是状态代码,第二列是Unix纪元以来的毫秒时间戳,第三列是未使用位置的geohash字符串,第四列是湿度百分比,第五列是雪现值0.0或1.0,第六列是云量百分比,第七列是雷击次数,第八个是未知的压力单位,但数据未使用,因此无所谓,第九个是以开尔文测量的表面温度。我意识到我必须转换时间戳和表面温度,所以我不担心这一点。我需要在一个完整的状态中聚合数据,而不考虑geohash,跟踪最低和最高温度以及它们发生的时间,并计算该状态的记录数,以便可以平均值

单个状态的输出应如下所示:

 * Opening file: data_tn.tdv
 * States found: TN
 * -- State: TN --
 * Number of Records: 17097
 * Average Humidity: 49.4%
 * Average Temperature: 58.3F
 * Max Temperature: 110.4F on Mon Aug  3 11:00:00 2015
 * Min Temperature: -11.1F on Fri Feb 20 04:00:00 2015
 * Lightning Strikes: 781
 * Records with Snow Cover: 107
 * Average Cloud Cover: 53.0%
但是,将有多个状态,每个状态都有自己的要处理的数据文件

正如您所看到的,第一个令牌将被分配给状态代码,但是我不知道如何做到这一点。我尝试了许多strcpy和其他方法,试图将令牌发送到各自的字段中,但都没有成功

     struct climate_info
        {
            char code[3];
            unsigned long num_records;
            unsigned long timestamp;
            char location[13];
            unsigned int humidity;
            int snow;
            unsigned int cover;
            int strikes;
            long double pressure;
            long double sum_temperature;
        };



struct stats
{
    char code[3];
    long long timestamp;
    double humidity;
    double snow;
    double cloud;
    double strikes;
    double sum_temperature;
}stats;



    void analyze_file(FILE *file, struct climate_info *states[], int num_states);
    void print_report(struct climate_info *states[], int num_states);

    int main(int argc, char *argv[])
    {
        /* TODO: fix this conditional. You should be able to read multiple files. */
        if (argc < 1 )
        {
            printf("Usage: %s tdv_file1 tdv_file2 ... tdv_fileN \n", argv[0]);
            return EXIT_FAILURE;
        }

        /* Let's create an array to store our state data in. As we know, there are
         * 50 US states. */
        struct climate_info *states[NUM_STATES] = { NULL };

        int i;
        for (i = 1; i < argc; ++i)
        {
            /* TODO: Open the file for reading */

            /* TODO: If the file doesn't exist, print an error message and move on
             * to the next file. */
            /* TODO: Analyze the file */
            /* analyze_file(file, states, NUM_STATES); */
            FILE *fp = fopen(argv[i], "r");
                if(fp == NULL)
                {
                    printf("Error opening file");
                    break;
                }
                 else if(fp)
                {
                 analyze_file(fp, states,NUM_STATES);
                }
             fclose(fp);
        }
        print_report(states, NUM_STATES);
        return 0;
    }

    void analyze_file(FILE *file, struct climate_info **states, int num_states)
    {
        const int line_sz = 100;
        char line[line_sz];
        int counter = 0;
        char *token;
        while (fgets(line, line_sz, file) != NULL)
        {
            /* TODO: We need to do a few things here:
             *
             *       * Tokenize the line.
             *       * Determine what state the line is for. This will be the state
             *         code, stored as our first token.
             *       * If our states array doesn't have a climate_info entry for
             *         this state, then we need to allocate memory for it and put it
             *         in the next open place in the array. Otherwise, we reuse the
             *         existing entry.
             *       * Update the climate_info structure as necessary.
             */
  struct climate_info *y = malloc(sizeof(struct climate_info)*num_states);
    token = strtok(line," \t");
    strcpy((y[counter]).code,token);
    counter++;
    printf("%s\n",token);
    while(token)
    {
        printf("token: %s\n", token);
        token = strtok(NULL, " \t");
    }
    printf("%d\n",counter);
        //free(states);
    }

    void print_report(struct climate_info *states[], int num_states)
    {
        printf("States found: ");
        int i;
        for (i = 0; i < num_states; ++i) {
            if (states[i] != NULL)
            {
                struct climate_info *info = states[i];
                printf("%s", info->code);
            }
        }
        printf("\n");

从文件中读取的值不应直接指定给结构的元素。您需要一组变量,它们可能在一个结构中,但不需要在读取数据时接收数据,sscanf将进行解析和拆分。然后验证状态代码是否正确,时间是否合理,等等。然后将累积信息添加到“统计结构”中,该结构与当前的结构气候信息相关,但不同。例如,它不需要geohash柱或压力柱,但需要最低温度和发现时间,以及最高温度和发现时间。您可以累积积雪数、雷击数、湿度、云量和当前温度。然后,当您完成该文件时,您可以平均温度、湿度和云量值,并可以打印聚合

因为您明智地使用FGET从文件中读取行,所以不要更改它!,您应该使用sscanf来解析该行。你需要:

状态代码char state[3];, 一个长时间的时间值;, 湿度值是湿度的两倍;, “雪现值”是雪的两倍;由于格式为浮点数, “云量”值为双云量;, 雷击值为双雷击, 温度值为温度的两倍;。 然后你就可以使用

if (sscanf(line, "%2[A-Z] %lld %*s %lf %lf %lf %lf %*lf %lf",
           state, &millitime, &humidity, &snow, &cloud, &lightning, &temperature) == 7)
{
    …validate data and report errors if appropriate…
    …stash values appropriately; increment the count…
}
else
{
    …report format error?… 
}
注意,格式中的*禁止赋值;该列已读取,但被忽略。代码检查压力是否为数字列;它不会验证“它必须存在”之外的geohash列。可以将大小指定为上限%*12s


使用fgets和sscanf的许多优点之一是,您可以更清楚地报告错误-您可以说第XXX行中的状态代码不正确:然后打印该行,因为您仍然可以使用该行。使用fscanf,您将无法如此轻松地报告行的内容,这使得调试数据的人更加困难。

您想用C编写这篇文章有什么特别的原因吗,特别是如果您还不熟悉该语言?问题是您认为您正在填充主状态,但实际上您只是填充了一个临时y,然后在不使用的情况下丢失和泄漏?我的问题是,为什么我无法通过使用每行的第一个标记来填充气候信息中的状态代码字段分析文件功能@JOHN3136从文件读取的值不应直接分配给结构的元素。您需要一组变量,它们可能在一个结构中,但不需要在读取数据时接收数据,fscanf进行解析和拆分。然后验证状态代码是否正确,时间是否合理,等等。[…continued…][…continuent…]然后将累积信息添加到“统计结构”中,该结构不需要geohash列(例如)或pressure列,但需要最低温度和发现的时间,以及最高温度和发现的时间。您可以累积积雪数、雷击数、湿度、云量和当前温度。然后,当您完成该文件时,您可以平均温度、湿度和云量值,并且您可以
打印聚合。当我尝试执行此操作时,我得到错误状态、毫秒、雪花等。。。是未声明的修饰符。我用if-sscanf…==7在代码上方的项目符号列表中显示了标识符的声明。噢,哇!我很抱歉;我没有意识到您不理解变量需要在analyze_file函数中定义——我从来没有想到它们可能被放在其他地方。即使在Java中,也会限制范围。我会在主体的顶部定义它们,而fgetsline,sizeofline,fp!=0循环,紧接在使用它们的sscanf调用之前。最小化变量的范围;避免像瘟疫一样的全局变量。如果愿意,您可以将声明放在函数的顶部,但这是老式的C编程;然后在对sscanf的调用中记录.millitime等(&R)。你也需要用闪电代替闪电。字符数组前面没有符号传递给'sscanf'等人。