Reputation: 11
I'm trying to create a C program to read and input the available information from a file called records.txt into a linked list and trying to print it as a simple test, but I'm not sure where the program went wrong since it's not inputting or printing anything at all. Any suggestions would be extremely helpful.
records.txt goes by: data code(int), state(string), town name(string), population(int), area(float), longitude(float), latitude(float), travel code(int), and travel distance(float)
// The lines from records.txt file to input:
2564273NYKirby 57 0.108676 43.803003-108.180310 6344 3.3662
7483946WYNewville 2085 2.435594 30.659203 -93.89685227591 0.9094
6394057HKickersville 520 1.963467 39.958220 -82.59599812626 0.2182
9174015ILWorkland Springs 1166 1.125451 42.091306 -88.850345 9110 7.4211
2373597NCFunland 579 8.390613 34.301093 -77.78746720394 3.5175
9533594WAKirkland 45054 10.675565 47.685821-122.191729 386 0.3655
7183994INHappy Mines 766 0.323048 40.193940 -86.36009213178 4.7952
0194152IAMoonville 76 0.285352 41.728980 -95.26655811596 5.1724
// The C Program so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dlfcn.h>
#include <unistd.h>
// places record
typedef struct records{
char state[2], name[30];
int code, popul, interCode;
float area, latit, longit, interDist;
} records;
// linked list with places record
typedef struct node{
records data;
struct node *next;
} node, *list;
// insert a record into list
void insert_list (list *L, records data) {
node *p;
// get a free node
p = (node *) malloc (sizeof (node));
// put the record in it
p->data = data;
// link it to the first node in the list
p->next = *L;
// make the first node equal to this one
// (so now the former first, p->next, is the second)
*L = p;
}
// create an empty list
void create_list (list *L) {
*L = NULL;
}
// main program
int main () {
list data; // data list of records.txt
records r, *p = NULL;
FILE * fin;
// open the file if possible otherwise error displayed
fin = fopen ("records.txt", "r");
if (!fin) {
perror ("records.txt");
exit (1);
}
// make an empty list
create_list (&data);
// read records, inserting them into the list
while (1) {
fscanf (fin, "%d %s %s %d %f %f %f %d %f",
&r.code, r.state, r.name, &r.popul,
&r.area, &r.latit, &r.longit, &r.interCode, &r.interDist);
// if reached end of file get out of loop
if (feof (fin)) break;
insert_list (&data, r);
// test print
printf ("%d %s %s %d %f %f %f %d %f\n", p->code, p->state, p->name, p->popul,
p->area, p->latit, p->longit, p->interCode, p->interDist);
}
fclose (fin);
exit (0);
}
Upvotes: 1
Views: 50
Reputation: 409374
A major problem is that e.g. %s
reads space-delimited "words". If you have e.g. NYKirby
then that will be read as a single word.
Another major problem is that %s
writes null-terminated byte strings to your arrays. And you need to reserve space for the null-terminator. A string of length 2
needs space for 3
characters.
The first problem can be solved by using field-width specifiers, like e.g. %2s
to read only two characters.
The second problem can be solved by increasing the size of your arrays.
There's also a third problem, which is that you don't check what fscanf
returns. You need to do this to check for errors.
This leaves you with the problem of reading strings containing space in them, like Workland Springs
.
A potential way to solve it is to use the %[]
format instead, to specify that only letters and spaces could be read by fscanf
. Perhaps like %29[A-Za-z ]
. It will however also read the trailing spaces after the name, which you then need to strip.
Upvotes: 2