0
votes

My assignment is to take input from a txt file and read that into parts of a struct array, then manipulate it, but I'm having trouble with reading from the file.

my struct is as follows:

   typedef struct Employee
   {
        char first[7], initial, last[9], street[16], city[11], state[2], zip[5];
        int age;
        char sex;
        int tenure;
        float salary;
   } Employee;

and within my main: I have defined MAX to be 100

FILE *payfile;
Employee worker[MAX];
int i = 0, num;
float average;

payfile = fopen("payfile.txt","r");

while(!feof(payfile))
 {
      fscanf(payfile,"%s %c %s %s %s %s %s %d %c %d %f",
        worker[i].first,&worker[i].initial,worker[i].last,worker[i].street,
        worker[i].city,worker[i].state,worker[i].zip,&worker[i].age,&worker[i].sex,
        &worker[i].tenure,&worker[i].salary);
      i++;
 }

here is the txt file we are to read from:

    ADA     A AGUSTA    33 BABBAGE ROAD  LOVELACE    GB 19569 28 F 2 350.50
    ISSAC   A ASIMOV    99 FICTION WAY   AMHERST     MA 63948 58 M 6 423.88
    HUMPHRY R BOGART    71 SAM STREET    HOLLYWOOD   CA 48482 56 M 5 366.00
    ALBERT  G EINSTEIN  94 ENERGY WAY    PRINCETON   NJ 47474 67 M 8 780.00
    EMMYLOU L HARRIS    66 COUNTRY ROAD  NASHVILLE   TN 72647 38 F 2 767.42
    JAMES   T KIRK      11 SPACE STREET  VULCAN      CA 82828 46 M 1 235.70
    TED     L KOPPEL    55 ABC PLACE     WASHINGTON  DC 37376 48 M 9 909.44
    DAVID   T LETTERMAN 14 WNBC AVENUE   NEW YORK    NY 19338 47 M 5 445.65
    STEVIE  R NICKS     31 MUSIC ROAD    CHICAGO     IL 23459 38 F 8 460.88
    MONTY   P PYTHON    76 SILLY STREET  LONDON      GB 80939 44 M 2 320.50
    ROGER   R RABBIT    15 LOONEY TOONS  HOLLYWOOD   CA 91343 24 M 4 259.53
    SALLY   W RIDE      21 COLUMBIA WAY  HOUSTON     TX 91123 30 F 9 707.80
    ROD     Q SERLING   11 TWLIGHT ZONE  SAN DIEGO   CA 93939 56 M 1 440.00
    LUKE    R SKYWALKER 43 MILKY WAY     NEW YORK    NY 12343 35 M 5 660.00

so I'm having some trouble with fscanf accuracy. To check what worker is containing, I'm using printf("%s",worker[0].first) and printf("%c",worker[0].initial) ... etc.

When I scan for the first string in the first line, I get ADA, then scan for whitespace and get the next char, A. Good so far. Then I scan for white space and take the the next string, which returns AGUSTA. But now I run into this problem. I need to get 33 BABBAGE ROAD into worker[0].street, but changing the parameter "%s " to "%16c " doesn't work. It instead includes part of the city.

What am I doing wrong? What do I change to scan the respective lines of code with correct accuracy?

Thanks.

2
Forget scanf(), use fgets() (safer anyway) and strtok_r(). - user529758
Thanks. fgets seems to work much better. - Adam Schachne

2 Answers

1
votes
char first[7], initial, last[9], street[16], city[11], state[2], zip[5];

char size is not enough including the EOS if you want to read with strings (C string).

change to

typedef struct Employee {
     char first[8], initial, last[10], street[17], city[12], state[3], zip[6];
     int age;
     char sex;
     int tenure;
     float salary;
} Employee;

control character %s in scanf reading with a space-delimited, specify read size and unread charactor, follow for example.

    while(EOF!=fscanf(payfile,"%7s %c %9s %16[^\n] %11[^\n] %2s %5s %d %c %d %f",
          worker[i].first,&worker[i].initial,worker[i].last,worker[i].street,
          worker[i].city,worker[i].state,worker[i].zip,&worker[i].age,&worker[i].sex,
          &worker[i].tenure,&worker[i].salary))
    {
        i++;
    }

You can delete if not required for trailing spaces then.

0
votes

You could read the street in as a series of strings, ie %s %s %s. Then concatenate them with strcat() into one string.

This is not a general solution because streets with more than 3 words (eg "19 N 3rd street") will fail. But I suspect it's good enough for your assignment. In a real life application the fields would be separated with some sort of a delimiter, usually a comma (see .csv). Since that doesn't seem to exist in your application, just do it this way and then tell your teacher to give you better assignments in the future.