C语言 我想读取一个文件并将它们保存到struct数组中,我该怎么做?



我对文件和结构很陌生,我只是不知道怎么做。现在,我试着到处找方法,但我找不到。这是我的代码。

#include <stdio.h>
typedef struct
{
int site_id_num;
int day_of_month[14];
int wind_speed[14];
int temperature[14];
}measured_data_t;
int main()
{
FILE *read;
measured_data_t station[5];
read = fopen("data", "r");
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 14; j++)
{
fscanf(read, "%d %d %d %d", station[i].site_id_num, station[i].day_of_month[j], station[i].wind_speed[j], station[i].temperature[j]);
}
}
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 14; j++)
{
printf("%d %d %d %dn", station[i].site_id_num, station[i].day_of_month[j], station[i].wind_speed[j], station[i].temperature[j]);
}
}

fclose(read);
return 1;   
}

这是我想要读取并保存到struct数组中的文本文件

1000 1 6 22
1000 2 9 21
1000 3 15 27
1000 4 24 26
1000 5 11 23
1000 6 24 22
1000 7 21 16
1000 8 10 20
1000 9 22 22
1000 10 3 25
1000 11 14 32
1000 12 23 33
1000 13 4 22
1000 14 25 35
2000 1 13 20
2000 2 1 28
2000 3 18 31
2000 4 2 34
2000 5 4 31
2000 6 18 15
2000 7 10 34
2000 8 14 33
2000 9 12 25
2000 10 11 24
2000 11 6 21
2000 12 12 26
2000 13 17 35
2000 14 20 25
3000 1 5 23
3000 2 17 33
3000 3 20 19
3000 4 7 35
3000 5 17 16
3000 6 2 28
3000 7 13 15
3000 8 23 33
3000 9 19 19
3000 10 16 27
3000 11 21 28
3000 12 22 18
3000 13 11 20
3000 14 1 32
4000 1 10 30
4000 2 2 28
4000 3 24 19
4000 4 11 22
4000 5 25 26
4000 6 1 23
4000 7 24 16
4000 8 13 24
4000 9 23 28
4000 10 2 15
4000 11 3 24
4000 12 7 28
4000 13 17 16
4000 14 10 18
5000 1 12 31
5000 2 10 24
5000 3 3 18
5000 4 25 16
5000 5 14 21
5000 6 11 24
5000 7 15 29
5000 8 4 28
5000 9 2 28
5000 10 22 21
5000 11 9 18
500 12 11 16
5000 13 2 33
5000 14 21 27

我希望每个站点都有id, 14天,14个风速和14个温度。但我现在没有任何线索。请帮帮我。

如果你的数据确实是这样的固定格式,那么你只需要在调用fscanf()时传递变量的地址。初始化数组,这样如果数据不符合,至少可以得到0值。检查fscanf()的返回值以确保您读取了4个数字。使用sizeof()代替硬编码数组大小。不要返回1,这意味着有错误。

#include <stdio.h>
typedef struct {
int site_id_num;
int day_of_month[14];
int wind_speed[14];
int temperature[14];
} measured_data_t;
int main(void) {
FILE *read = fopen("data", "r");
measured_data_t station[5] = { 0 };
for(size_t i = 0; i < sizeof station / sizeof *station; i++) {
for(size_t j = 0; j < sizeof station->day_of_month / sizeof *station->day_of_month; j++) {
int r = fscanf(read, "%d %d %d %d",
&station[i].site_id_num,
&station[i].day_of_month[j],
&station[i].wind_speed[j],
&station[i].temperature[j]
);
if(r != 4) {
printf("fscanf failedn");
return 1;
}
}
}
fclose(read);
for(size_t i = 0; i < sizeof station / sizeof *station; i++)
for(size_t j = 0; j < sizeof station->day_of_month / sizeof *station->day_of_month; j++)
printf("%d %d %d %dn", station[i].site_id_num, station[i].day_of_month[j], station[i].wind_speed[j], station[i].temperature[j]);
}

修复了一个正常编译器应该警告的错误:

main.c: In function ‘main’:
main.c:23:28: warning: format ‘%d’ expects argument of type ‘int *’, but argument 3 has type ‘int’ [-Wformat=]
23 |             fscanf(read, "%d %d %d %d", station[i].site_id_num, station[i].day_of_month[j], station[i].wind_speed[j], station[i].temperature[j]);
|                           ~^            ~~~~~~~~~~~~~~~~~~~~~~
|                            |                      |
|                            int *                  int
main.c:23:31: warning: format ‘%d’ expects argument of type ‘int *’, but argument 4 has type ‘int’ [-Wformat=]

等。

使用地址运算符&传递fscanf存储该值的变量的地址:

fscanf(read, "%d %d %d %d", &station[i].site_id_num, &station[i].day_of_month[j], &station[i].wind_speed[j], &station[i].temperature[j]);

代码中有更多的问题:

您应该检查所有*scanf函数的返回值。在您的情况下,它是转换项目的数量,预计为4。

最好使用fscanf读取一行输入,并使用sscanf解析字符串。这可以避免在输入行包含错误或多于或少于预期值的情况下不同步。

char line[100];
if(fgets(line, sizeof(line), read) == NULL)
{
/* handle EOF or error */
}
/* check for trailing newline to detect input lines that are too long */
if(sscanf(line, "%d %d %d %d", &station[i].site_id_num, &station[i].day_of_month[j], &station[i].wind_speed[j], &station[i].temperature[j]) != 4)
{
/* handle error */
}

您的代码以循环必须匹配(预测)输入的方式实现,即5个站点,每个站点有14条记录。我建议将数据读入临时结构或临时变量中,比较站点ID以检查是否有同一站点或下一个站点的下一个记录,并将数据复制到最终位置。

与其在结构中使用3个数组(实际上代表一组数据记录),我建议使用结构数组。

typedef struct
{
int site_id_num;
struct record {
int day_of_month;
int wind_speed;
int temperature;
} data[14];
}measured_data_t;

我建议将数据读入结构数组,例如下面的代码。

#include <stdio.h>
#include <stdlib.h>
typedef struct measured_data
{
int site_id_num;
int day_of_month;
int wind_speed;
int temperature;
} measured_data_t;
int main()
{
FILE *fp;
int stations = 5;
int measurements = 14;
measured_data_t data[stations * measurements];

if( (fp = fopen("data", "r")) == NULL )
{
printf("error opening filen");
exit(1);
}
int retv = 0;

for(int i = 0; i < stations * measurements && retv != EOF; i++ )
{  
retv = fscanf(fp, "%d %d %d %d", 
&data[i].site_id_num, 
&data[i].day_of_month, 
&data[i].wind_speed, 
&data[i].temperature);

}
for(int i = 0; i < stations * measurements ; i++ )
{  
printf( "%d %d %d %dn", 
data[i].site_id_num, 
data[i].day_of_month, 
data[i].wind_speed, 
data[i].temperature);

}

fclose(fp);
}

直接使用二进制文件I/O

写作:

fp = fopen("data.bin", "wb");
for(int i = 0; i < 5; i++)
fwrite(&station, 1, sizeof(measured_data_t), fp);

阅读:

fp = fopen("data.bin", "rb");
for(int i = 0; i < 5; i++)
fread(&station, 1, sizeof(measured_data_t), fp);

最新更新