如何将文件中的信息存储到C中的内存中
How do I store information from a file in to memory in C
我需要逐行阅读文件并使用从每一行收集的信息进行一些操作。到目前为止,我的代码只能逐行读取文件并在控制台打印。
#include <stdio.h>
#include <stdlib.h>
#include "structure.h"
int main()
{
printf("Hello world!\n");
int x = 43; // number of lines in my text file
FILE *fptr;
struct values *valuesPtr = malloc(sizeof(struct values) * x);
if (!valuesPtr)
return -1;
if((fptr = fopen("energy.txt", "r")) == NULL) {
printf ("Error opening file ");
return 0;
}
while (fptr != NULL) {
for(int i = 0; i < x; i++ ) {
fscanf(fptr, "%s %s %d", valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, &valuesPtr[i].num);
printf("\nStart vertex: %s \nDestination vertex: %s \nWeight: %d\n\n", valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, valuesPtr[i].num);
}
free(valuesPtr);
}
fclose(fptr);
return 0;
}
我的 structure.h 文件包含以下代码:
struct values{
int num;
char start_vertex[250];
char destination_vertex[250];
} x;
energy.txt 文件具有以下内容:
York Hull 60
Leeds Doncaster -47
Liverpool Nottingham 161
Manchester Sheffield 61
Reading Oxford -43
Oxford Birmingham 103
Birmingham Leicester 63
Liverpool Blackpool 79
Carlisle Newcastle 92
Nottingham Birmingham 77
Leeds York 39
Glasgow Edinburgh 74
Moffat Carlisle 65
Doncaster Hull 76
Northampton Birmingham 90
Leicester Lincoln 82
Sheffield Birmingham 122
Lincoln Doncaster 63
Sheffield Doncaster 29
Bristol Reading 130
Hull Nottingham 145
Blackpool Leeds 116
Birmingham Bristol 139
Manchester Leeds 64
Carlisle Blackpool 140
Leicester Northampton -61
Newcastle York 135
Glasgow Moffat -28
Leicester Sheffield 100
Carlisle Liverpool -30
Birmingham Manchester 129
Oxford Bristol 116
Leeds Hull 89
Edinburgh Carlisle 154
Nottingham Sheffield 61
Liverpool Manchester 56
Carlisle Glasgow 50
Sheffield Lincoln 74
York Doncaster 55
Newcastle Edinburgh 177
Leeds Sheffield 53
Northampton Oxford 68
Manchester Carlisle 20
我被告知使用 getline()
函数和 sscanf()
来存储文件中的数据。但我不确定我应该怎么做。
你的代码有几个问题
有
if((fptr = fopen("energy.txt", "r")) == NULL)
{
printf ("Error opening file ");
return 0;
}
while (fptr != NULL)
如果 fptr 为 NULL,并且 fptr 的值,则无法到达 while永不改变while的正文,这样一个是无限循环
另一个问题是在 for 之后你释放了 valuesPtr 所以从第二个回合你将在释放的内存中写入,意外记忆。很可能 while 只是没用,可以删除(当然 for 不能)。
假设 while 完成你尝试释放 fptr,但这不是关闭描述的方式,你必须调用fclose(fptr) 而不是 free,你的 free 有一个未定义的行为
我鼓励您通过 fscanf 检查值 return,目前您无法知道它是否成功。请注意,fscanf 也可以写出包含字符串的字段,因为您不限制要读取的字符数。
当您无法打开文件时,您可以使用 perror:
给出原因
perror("Error opening file");
您修改后的提案:
#include <stdio.h>
#include <stdlib.h>
typedef struct value {
int num;
char start_vertex[250];
char destination_vertex[250];
} value;
int main()
{
const int nLines = 43; // number of lines in my text file
FILE * fptr;
value * valuesPtr = malloc(sizeof(value) * nLines);
if (!valuesPtr) {
puts("cannot allocate memory");
return -1;
}
if((fptr = fopen("energy.txt", "r")) == NULL)
{
perror("Error opening file");
return -1;
}
for(int i = 0; i < nLines; i++ )
{
if (fscanf(fptr, "%249s %249s %d",
valuesPtr[i].start_vertex,
valuesPtr[i].destination_vertex,
&valuesPtr[i].num) != 3) {
printf("errored file line %d\n", i);
break;
}
printf("\nStart vertex: %s \nDestination vertex: %s \nWeight: %d\n\n",
valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, valuesPtr[i].num);
}
free(valuesPtr);
fclose(fptr);
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall l.c
pi@raspberrypi:/tmp $ ./a.out
Start vertex: York
Destination vertex: Hull
Weight: 60
Start vertex: Leeds
Destination vertex: Doncaster
Weight: -47
Start vertex: Liverpool
Destination vertex: Nottingham
Weight: 161
Start vertex: Manchester
Destination vertex: Sheffield
Weight: 61
Start vertex: Reading
Destination vertex: Oxford
Weight: -43
Start vertex: Oxford
Destination vertex: Birmingham
Weight: 103
Start vertex: Birmingham
Destination vertex: Leicester
Weight: 63
Start vertex: Liverpool
Destination vertex: Blackpool
Weight: 79
Start vertex: Carlisle
Destination vertex: Newcastle
Weight: 92
Start vertex: Nottingham
Destination vertex: Birmingham
Weight: 77
Start vertex: Leeds
Destination vertex: York
Weight: 39
Start vertex: Glasgow
Destination vertex: Edinburgh
Weight: 74
Start vertex: Moffat
Destination vertex: Carlisle
Weight: 65
Start vertex: Doncaster
Destination vertex: Hull
Weight: 76
Start vertex: Northampton
Destination vertex: Birmingham
Weight: 90
Start vertex: Leicester
Destination vertex: Lincoln
Weight: 82
Start vertex: Sheffield
Destination vertex: Birmingham
Weight: 122
Start vertex: Lincoln
Destination vertex: Doncaster
Weight: 63
Start vertex: Sheffield
Destination vertex: Doncaster
Weight: 29
Start vertex: Bristol
Destination vertex: Reading
Weight: 130
Start vertex: Hull
Destination vertex: Nottingham
Weight: 145
Start vertex: Blackpool
Destination vertex: Leeds
Weight: 116
Start vertex: Birmingham
Destination vertex: Bristol
Weight: 139
Start vertex: Manchester
Destination vertex: Leeds
Weight: 64
Start vertex: Carlisle
Destination vertex: Blackpool
Weight: 140
Start vertex: Leicester
Destination vertex: Northampton
Weight: -61
Start vertex: Newcastle
Destination vertex: York
Weight: 135
Start vertex: Glasgow
Destination vertex: Moffat
Weight: -28
Start vertex: Leicester
Destination vertex: Sheffield
Weight: 100
Start vertex: Carlisle
Destination vertex: Liverpool
Weight: -30
Start vertex: Birmingham
Destination vertex: Manchester
Weight: 129
Start vertex: Oxford
Destination vertex: Bristol
Weight: 116
Start vertex: Leeds
Destination vertex: Hull
Weight: 89
Start vertex: Edinburgh
Destination vertex: Carlisle
Weight: 154
Start vertex: Nottingham
Destination vertex: Sheffield
Weight: 61
Start vertex: Liverpool
Destination vertex: Manchester
Weight: 56
Start vertex: Carlisle
Destination vertex: Glasgow
Weight: 50
Start vertex: Sheffield
Destination vertex: Lincoln
Weight: 74
Start vertex: York
Destination vertex: Doncaster
Weight: 55
Start vertex: Newcastle
Destination vertex: Edinburgh
Weight: 177
Start vertex: Leeds
Destination vertex: Sheffield
Weight: 53
Start vertex: Northampton
Destination vertex: Oxford
Weight: 68
Start vertex: Manchester
Destination vertex: Carlisle
Weight: 20
pi@raspberrypi:/tmp $
我冒昧地将values重命名为value因为struct保存了一个元素而不是几个,无论如何我鼓励您将其重命名为更精确的名称,value 非常笼统。我还使用了 typedef 来不必在每个使用它的地方都需要 struct。
查看详细信息,例如对于字符串,我使用格式 %249s 因为数组有 250 个字符(我为最后一个空字符删除了 1 个),并且当然我检查它读取 3 个元素。
我需要逐行阅读文件并使用从每一行收集的信息进行一些操作。到目前为止,我的代码只能逐行读取文件并在控制台打印。
#include <stdio.h>
#include <stdlib.h>
#include "structure.h"
int main()
{
printf("Hello world!\n");
int x = 43; // number of lines in my text file
FILE *fptr;
struct values *valuesPtr = malloc(sizeof(struct values) * x);
if (!valuesPtr)
return -1;
if((fptr = fopen("energy.txt", "r")) == NULL) {
printf ("Error opening file ");
return 0;
}
while (fptr != NULL) {
for(int i = 0; i < x; i++ ) {
fscanf(fptr, "%s %s %d", valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, &valuesPtr[i].num);
printf("\nStart vertex: %s \nDestination vertex: %s \nWeight: %d\n\n", valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, valuesPtr[i].num);
}
free(valuesPtr);
}
fclose(fptr);
return 0;
}
我的 structure.h 文件包含以下代码:
struct values{
int num;
char start_vertex[250];
char destination_vertex[250];
} x;
energy.txt 文件具有以下内容:
York Hull 60
Leeds Doncaster -47
Liverpool Nottingham 161
Manchester Sheffield 61
Reading Oxford -43
Oxford Birmingham 103
Birmingham Leicester 63
Liverpool Blackpool 79
Carlisle Newcastle 92
Nottingham Birmingham 77
Leeds York 39
Glasgow Edinburgh 74
Moffat Carlisle 65
Doncaster Hull 76
Northampton Birmingham 90
Leicester Lincoln 82
Sheffield Birmingham 122
Lincoln Doncaster 63
Sheffield Doncaster 29
Bristol Reading 130
Hull Nottingham 145
Blackpool Leeds 116
Birmingham Bristol 139
Manchester Leeds 64
Carlisle Blackpool 140
Leicester Northampton -61
Newcastle York 135
Glasgow Moffat -28
Leicester Sheffield 100
Carlisle Liverpool -30
Birmingham Manchester 129
Oxford Bristol 116
Leeds Hull 89
Edinburgh Carlisle 154
Nottingham Sheffield 61
Liverpool Manchester 56
Carlisle Glasgow 50
Sheffield Lincoln 74
York Doncaster 55
Newcastle Edinburgh 177
Leeds Sheffield 53
Northampton Oxford 68
Manchester Carlisle 20
我被告知使用 getline()
函数和 sscanf()
来存储文件中的数据。但我不确定我应该怎么做。
你的代码有几个问题
有
if((fptr = fopen("energy.txt", "r")) == NULL)
{
printf ("Error opening file ");
return 0;
}
while (fptr != NULL)
如果 fptr 为 NULL,并且 fptr 的值,则无法到达 while永不改变while的正文,这样一个是无限循环
另一个问题是在 for 之后你释放了 valuesPtr 所以从第二个回合你将在释放的内存中写入,意外记忆。很可能 while 只是没用,可以删除(当然 for 不能)。
假设 while 完成你尝试释放 fptr,但这不是关闭描述的方式,你必须调用fclose(fptr) 而不是 free,你的 free 有一个未定义的行为
我鼓励您通过 fscanf 检查值 return,目前您无法知道它是否成功。请注意,fscanf 也可以写出包含字符串的字段,因为您不限制要读取的字符数。
当您无法打开文件时,您可以使用 perror:
给出原因perror("Error opening file");
您修改后的提案:
#include <stdio.h>
#include <stdlib.h>
typedef struct value {
int num;
char start_vertex[250];
char destination_vertex[250];
} value;
int main()
{
const int nLines = 43; // number of lines in my text file
FILE * fptr;
value * valuesPtr = malloc(sizeof(value) * nLines);
if (!valuesPtr) {
puts("cannot allocate memory");
return -1;
}
if((fptr = fopen("energy.txt", "r")) == NULL)
{
perror("Error opening file");
return -1;
}
for(int i = 0; i < nLines; i++ )
{
if (fscanf(fptr, "%249s %249s %d",
valuesPtr[i].start_vertex,
valuesPtr[i].destination_vertex,
&valuesPtr[i].num) != 3) {
printf("errored file line %d\n", i);
break;
}
printf("\nStart vertex: %s \nDestination vertex: %s \nWeight: %d\n\n",
valuesPtr[i].start_vertex, valuesPtr[i].destination_vertex, valuesPtr[i].num);
}
free(valuesPtr);
fclose(fptr);
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall l.c
pi@raspberrypi:/tmp $ ./a.out
Start vertex: York
Destination vertex: Hull
Weight: 60
Start vertex: Leeds
Destination vertex: Doncaster
Weight: -47
Start vertex: Liverpool
Destination vertex: Nottingham
Weight: 161
Start vertex: Manchester
Destination vertex: Sheffield
Weight: 61
Start vertex: Reading
Destination vertex: Oxford
Weight: -43
Start vertex: Oxford
Destination vertex: Birmingham
Weight: 103
Start vertex: Birmingham
Destination vertex: Leicester
Weight: 63
Start vertex: Liverpool
Destination vertex: Blackpool
Weight: 79
Start vertex: Carlisle
Destination vertex: Newcastle
Weight: 92
Start vertex: Nottingham
Destination vertex: Birmingham
Weight: 77
Start vertex: Leeds
Destination vertex: York
Weight: 39
Start vertex: Glasgow
Destination vertex: Edinburgh
Weight: 74
Start vertex: Moffat
Destination vertex: Carlisle
Weight: 65
Start vertex: Doncaster
Destination vertex: Hull
Weight: 76
Start vertex: Northampton
Destination vertex: Birmingham
Weight: 90
Start vertex: Leicester
Destination vertex: Lincoln
Weight: 82
Start vertex: Sheffield
Destination vertex: Birmingham
Weight: 122
Start vertex: Lincoln
Destination vertex: Doncaster
Weight: 63
Start vertex: Sheffield
Destination vertex: Doncaster
Weight: 29
Start vertex: Bristol
Destination vertex: Reading
Weight: 130
Start vertex: Hull
Destination vertex: Nottingham
Weight: 145
Start vertex: Blackpool
Destination vertex: Leeds
Weight: 116
Start vertex: Birmingham
Destination vertex: Bristol
Weight: 139
Start vertex: Manchester
Destination vertex: Leeds
Weight: 64
Start vertex: Carlisle
Destination vertex: Blackpool
Weight: 140
Start vertex: Leicester
Destination vertex: Northampton
Weight: -61
Start vertex: Newcastle
Destination vertex: York
Weight: 135
Start vertex: Glasgow
Destination vertex: Moffat
Weight: -28
Start vertex: Leicester
Destination vertex: Sheffield
Weight: 100
Start vertex: Carlisle
Destination vertex: Liverpool
Weight: -30
Start vertex: Birmingham
Destination vertex: Manchester
Weight: 129
Start vertex: Oxford
Destination vertex: Bristol
Weight: 116
Start vertex: Leeds
Destination vertex: Hull
Weight: 89
Start vertex: Edinburgh
Destination vertex: Carlisle
Weight: 154
Start vertex: Nottingham
Destination vertex: Sheffield
Weight: 61
Start vertex: Liverpool
Destination vertex: Manchester
Weight: 56
Start vertex: Carlisle
Destination vertex: Glasgow
Weight: 50
Start vertex: Sheffield
Destination vertex: Lincoln
Weight: 74
Start vertex: York
Destination vertex: Doncaster
Weight: 55
Start vertex: Newcastle
Destination vertex: Edinburgh
Weight: 177
Start vertex: Leeds
Destination vertex: Sheffield
Weight: 53
Start vertex: Northampton
Destination vertex: Oxford
Weight: 68
Start vertex: Manchester
Destination vertex: Carlisle
Weight: 20
pi@raspberrypi:/tmp $
我冒昧地将values重命名为value因为struct保存了一个元素而不是几个,无论如何我鼓励您将其重命名为更精确的名称,value 非常笼统。我还使用了 typedef 来不必在每个使用它的地方都需要 struct。
查看详细信息,例如对于字符串,我使用格式 %249s 因为数组有 250 个字符(我为最后一个空字符删除了 1 个),并且当然我检查它读取 3 个元素。