3

Okay. I have a file called "Graduates.txt" in my home directory.
I have a portable program to find the home directory, and I opened the file for reading.
Data in the file looks something like this:

year,firstName,lastName

I need to get this data from this file, and separate it into my struct:

typedef struct alumnus {

    int yearGraduated;
    char firstName[30];
    char lastName[30];

} Alumns;

I have a thought that may or may not work:
A while loop reads through the file, using fgets() to get the data. It then copies it to the struct... but I don't know how to implement any of this.

Sorry if this sounds like dumb question, it most likely is.

Sir_Mr_Bman
  • 227
  • 1
  • 4
  • 11
  • 1
    You might want to read about [`strtok`](http://en.cppreference.com/w/c/string/byte/strtok). – Some programmer dude Oct 19 '13 at 14:07
  • 1
    Copying the data is a waste of time. Make the members of the struct pointers, with one member a large buffer (even better, a pointer that can be resized so that you don't have a fixed upper bound on the maximum line length). Read each line into the large buffer using fgets, find the commas and replace them with a nul byte, and set each of the member pointers to the character after the nul. – William Pursell Oct 19 '13 at 14:21
  • It is not a dumb question, but a complex one because C does not help you avoid any of the possible pitfalls. You need to be really careful if you are thinking about letting others write to your Graduates.txt file. If this is not an educational task to learn C, i would strongly recommend using a different language. – ivarne Oct 19 '13 at 14:23
  • 2
    If you have a thought on approach, take a shot at it and show your code. A lot of learning to figure out problems like this is to try things and experience first hand the thought process, the pitfalls, and the subsequent needed corrections. – lurker Oct 19 '13 at 14:26
  • @dasblinkenlight looks like you got the formats backwards, should be `"%d,%s,%s"` – Kevin Oct 19 '13 at 14:38
  • Hint: `fscanf(f, "%d,%s,%s", &year, first, last)` – Sergey Kalinichenko Oct 19 '13 at 14:48
  • 1
    @JoachimPileborg You misspelled `strtok_r()` :P –  Oct 19 '13 at 15:01
  • @H2CO3 - You are a strong proponent of the re-entrant version of `strtok()`, even for code that is clearly not targeted for threading issues. Have you posted your reasons? I would be interested in reading. Thanks. – ryyker Oct 19 '13 at 15:26
  • @ryyker Simple: 1. I hate implicit state because it's hard to read/perceive; 2. if I always use the reentrant version, I don't have to think about in which situation I should use the re-entrant variant and when I can also use the non-reentrant function. Programming is already hard, so there's no need to make it even harder *for ourselves.* –  Oct 19 '13 at 15:30

3 Answers3

3
#include <stdio.h>

typedef struct alumnus {
    int yearGraduated;
    char firstName[30];
    char lastName[30];
}Alumns;

int main(void) {

    Alumns REC1;

    FILE *fptr;
    fptr = fopen("Test.txt", "r");

    fscanf(fptr, "%d,%s,%s", &REC1.yearGraduated, REC1.firstName, REC1.lastName);

    printf("%d, %s, %s", REC1.yearGraduated, REC1.firstName, REC1.lastName);
}

Implemented using dasblinkenlight hint.

Anand
  • 374
  • 2
  • 11
  • I'm getting a BAD ACCESS error on the fscanf line, @ "%d" It's saying that %d is type int * and yearDraduated is int, how do I fix this? – Sir_Mr_Bman Oct 19 '13 at 16:55
  • hmm.. Have u created the file "Test.txt" with content **1000,Name1,Name2** before running the program? – Anand Oct 19 '13 at 17:14
  • I know this is an extremely old post, but will reading the file into the structure like that, move the file pointer further into the text file. In essence, would this be able to be preformed in a loop in order to fill an array of structs? – beckah Apr 16 '15 at 14:09
  • @beckah: Yes. you can do in a loop to fill array of structs. – Anand Sep 20 '15 at 21:30
  • Where are you splitting the line using `strtok`? – Kiran Reddy Oct 29 '17 at 13:12
2
  1. Use fgets to read a line from file
  2. Use String Tokenization to separate the individual elements

Use strtok() for the same. e.g

   FILE *fp;
   fp = fopen("path", "r");
   char string[150];
   char *token;

   while(!feof(fp)) {
       if (fgets(string,150,fp)) {
           printf("%s\n", string);
           token=strtok(string,",");
           /*Store this token in your struct(your first element) */ 
       }
   }

3.Remember strtok() is non-reentrant function,so store the results returned from evey function call of strtok();

beckah
  • 1,543
  • 6
  • 28
  • 61
uni
  • 117
  • 4
  • 1
    Use `strtok_r()` which is reentrant instead of hacking. Also change the hard-coded size from 150 to `sizeof string`. And don't name it "string". Name it "line" or "buffer" or "tmp"... Furthermore, [`while(!feof(f))` is almost always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). –  Oct 19 '13 at 15:01
  • Thanks H2CO3 for suggesting much better function !! – uni Oct 19 '13 at 15:03
0

Here is a quick example of reading input, using fopen(), fgets() and strtok() and how to format output using correct format strings: (output shown here)

enter image description here

Edited to show placing values into struct Alums

 #include <ansi_c.h>

typedef struct alumnus {  //Note "alumnus" is not necessary here, you have Alumns 
    int yearGraduated;    //below that will satisfy naming the typedef struct
    char firstName[30];
    char lastName[30];

}Alumns;

Alumns a, *pA;  //Create copy of struct Alumns to use

#define FILE_LOC  "C:\\dev\\play\\file10.txt"

int main(void)
{
    FILE *fp;
    char *tok;
    char input[80];

    pA = &a;  //initialize struct

    fp = fopen(FILE_LOC, "r");  //open file (used #define, change path for your file)
    fgets(input, 80, fp);
    tok = strtok(input, ", \n"); //You can also call strtok in loop if number of items unknown
    pA->yearGraduated= atoi(input); //convert this string in to integer
    tok = strtok(NULL, ", \n");
    strcpy(pA->firstName, tok); //copy next two strings into name variables
    tok = strtok(NULL, ", \n");
    strcpy(pA->lastName, tok);
    //note the format strings here for int, and char *
    printf("age:%d\n First Name: %s\n Last Name: %s\n", 
             pA->yearGraduated, pA->firstName, pA->lastName);
    getchar();  //used so I can see output
    fclose(fp);
    return 0;
}
ryyker
  • 22,849
  • 3
  • 43
  • 87