Reputation: 5
I need to read through a file line by line and use the information gathered from each line to do a few manipulations. So far, my code can only read the file line by line and print it in the console.
#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;
}
My structure.h file has the following code:
struct values{
int num;
char start_vertex[250];
char destination_vertex[250];
} x;
The energy.txt file has the following content:
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
I have been told to use getline()
function and sscanf()
to store the data from the file. But I am not sure how I should do it.
Upvotes: 0
Views: 62
Reputation: 32596
There are several problems in your code
Having
if((fptr = fopen("energy.txt", "r")) == NULL)
{
printf ("Error opening file ");
return 0;
}
while (fptr != NULL)
you cannot reach the while if fptr is NULL, and the value of fptr never change in the body of the while, so that one is an infinite loop
An other problem is after the for you free valuesPtr so from the second turn you will write in freed memory, with an unexpected memory. Very probably that while is just useless and can be removed (but not the for of course).
Supposing the while finish you try to free fptr, but this is not the way to close a description, you have to call fclose(fptr) rather than free, your free has an undefined behavior
I encourage you to check the value return by fscanf, currently you cannot know if it success or not. Note that fscanf can also write out of the fields containing a string because you do not limit the number of char to read.
When you cannot open the file you can give the reason using perror:
perror("Error opening file");
A proposal after your edit :
#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;
}
Compilation and execution :
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 $
I taken the liberty to rename values to value because that struct save one element rather than several, anyway I encourage you to rename it to something more precise, value is very general. I also used a typedef to not have to need a struct every where it is used.
Look at the details, for instance for the string I use the format %249s because the arrays have 250 characters (I removed 1 for the final null character), and of course I check it reads 3 elements.
Upvotes: 1