Yang
Yang

Reputation: 11

Inputing a special text file into linked list and trying to print

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

Answers (1)

Some programmer dude
Some programmer dude

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

Related Questions