C 编程:读取文件并存储在结构数组中
Posted
技术标签:
【中文标题】C 编程:读取文件并存储在结构数组中【英文标题】:C Programming: Reading a file and storing in array of struct 【发布时间】:2016-11-28 00:42:10 【问题描述】:我正在尝试通过 fscanf 读取文件 test.txt 并将其存储在结构数组中。这是我尝试过的。这里的问题是fscanf
没有按预期工作。读取文件后,我也尝试在屏幕上打印,但它不起作用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Item
double value;
int unit;
char name[50];
;
int load(struct Item* item, FILE* data);
void display(struct Item item, int variableA);
int main()
struct Item I;
int i;
char ck;
ck = fopen("test.txt", "r");
if (ck)
for (i = 0; i < 3; i++)
load(&I, ck);
display(I, 0); //DISPLAY FUNCTION THAT READS test.txt and DISPLAYS
fclose(ck);
return 0;
int load(struct Item* item, FILE* data)
fscanf(data, "%d,%.2lf,%s\n", &(*item).unit,&(*item).value,&(*item).name);
return 0;
void display(struct Item item, int variableA)
printf("|%3d |%12.2lf| %20s |***\n", item.unit, item.value, item.name);
return;
这是我在 test.txt 文件中的内容:
205,11.20,John Snow
336,23.40,Winter is coming
220,34.20,You know nothing
错误: 程序编译时出现一些警告,但执行代码时出现分段错误。
知道为什么吗?
输出预期:应该从 test.txt 文件中读取 OUTPUT 并显示在屏幕上。
【问题讨论】:
可能是因为“John”不正确;那是“乔恩”斯诺…… @ringø 哈哈 :D :D :D 您必须调试程序以查看错误发生的位置(读取或显示),并查看您是否得到了您认为应该得到的结果。 好吧,一方面,fopen
不返回 char
,它返回 FILE*
。不要忽视警告。他们在那里告诉你有什么问题。所以修复他们。
【参考方案1】:
程序中的多个问题:
1.
char ck;
ck = fopen("test.txt", "r");
fopen
返回 FILE*
,而不是 char
,使用
FILE* ck = fopen(...);
2.
fscanf(data, "%d,%.2lf,%s\n", &(*item).unit,&(*item).value,&(*item).name);
始终检查fscanf
的返回值,如果它小于您请求的字段数,则对fscanf
的以下调用不太可能达到您的预期。另外,*item.unit
和item->unit
一样,使用item->unit
,因为它更短更干净:
int ret = fscanf(data, "%d,%lf,", &item->unit, &item->value);
if (ret != 3) // error
第三,%s
匹配一系列非空白字符,因此当fscanf
读取“John”时,它将停止,并且下一个 fscanf
调用将读取“Snow”,同时期待整数。
所以要输入带有空格的字符串,请改用fgets
,并记住最后删除换行符。
尝试以下操作:
int main(void)
struct Item I;
int i;
FILE* ck;
int ret;
ck = fopen("test.txt", "r");
if (ck)
for (i = 0; i < 3; i++)
ret = load(&I, ck);
if (ret < 0)
break;
display(I, 0); //DISPLAY FUNCTION THAT READS test.txt and DISPLAYS
fclose(ck);
return 0;
int load(struct Item* item, FILE* data)
int ret = fscanf(data, "%d,%lf,", &item->unit, &item->value);
if (ret != 2)
return -1;
fgets(item->name, sizeof item->name, data);
item->name[strlen(item->name)-1] = '\0';
return 0;
void display(struct Item item, int variableA)
printf("|%3d |%12.2lf| %20s |***\n", item.unit, item.value, item.name);
return;
它输出:
$ ./a.out
|205 | 11.20| John Snow |***
|336 | 23.40| Winter is coming |***
|220 | 34.20| You know nothing |***
【讨论】:
Ty 提示解释。 :) 我仍然得到黑色输出。 @John 你能展示一下你是如何编译程序以及如何运行它的吗? gcc -Wall test.c 然后 ./a.out @John test.txt 存在吗?【参考方案2】:您可以尝试这种不同的方法。
它使用:
malloc
,realloc
为结构数组分配和重新分配内存。我假设将使用具有更多行的更大文本文件,这允许数组在需要时调整大小以容纳更多信息。
strtok
解析,
分隔符之间的每个数据,然后将它们存储到结构数组中。
检查指针的返回值以避免分段错误。
使用fgets
将文件的每一行读入一个字符串,之后我们可以从中解析自己。
这是建议的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAMESTRLEN 50
#define INITSIZE 3
#define MAXSIZE 100
typedef struct
int unit;
double value;
char name[NAMESTRLEN+1];
item_t;
typedef struct
item_t *items;
int numlines;
allitems_t;
allitems_t *initialize_arraystructs(void);
void print_arraystructs(allitems_t *allitems);
void read_insert_items(FILE *filestream, allitems_t *allitems);
void check_ptr(void *ptr, const char *msg);
int
main(void)
allitems_t *allitems;
FILE *fp;
fp = fopen("test.txt", "r");
if (fp == NULL)
fprintf(stderr, "%s\n", "Error reading file!\n");
exit(EXIT_FAILURE);
allitems = initialize_arraystructs();
read_insert_items(fp, allitems);
print_arraystructs(allitems);
return 0;
void
read_insert_items(FILE *filestream, allitems_t *allitems)
int count = 0;
char line[MAXSIZE];
char *unit, *value, *name;
size_t numitems = INITSIZE;
allitems->items = malloc(numitems * sizeof(item_t));
check_ptr(allitems->items, "Initial Allocation");
while (fgets(line, MAXSIZE, filestream) != NULL)
unit = strtok(line, ",");
value = strtok(NULL, ",");
name = strtok(NULL, "\n");
if (count == numitems)
numitems *= 2;
allitems->items = realloc(allitems->items, numitems * sizeof(item_t));
check_ptr(allitems->items, "Reallocation");
allitems->items[count].unit = atoi(unit);
allitems->items[count].value = atof(value);
strcpy(allitems->items[count].name, name);
count++;
allitems->numlines++;
allitems_t
*initialize_arraystructs(void)
allitems_t *allitems;
allitems = malloc(sizeof(allitems_t));
check_ptr(allitems, "Initial Allocation");
allitems->items = NULL;
allitems->numlines = 0;
return allitems;
void
print_arraystructs(allitems_t *allitems)
int i;
for (i = 0; i < allitems->numlines; i++)
printf("%d,%.2f,%s\n",
allitems->items[i].unit,
allitems->items[i].value,
allitems->items[i].name);
void
check_ptr(void *ptr, const char *msg)
if (!ptr)
printf("Unexpected null pointer: %s\n", msg);
exit(EXIT_FAILURE);
【讨论】:
以上是关于C 编程:读取文件并存储在结构数组中的主要内容,如果未能解决你的问题,请参考以下文章
C程序:从文件中读取矩阵数据,并显示出来,利用链式存储结构。