简体   繁体   中英

How to use fscanf and fgets from a text file with ints and strings?

Example file:

School Name (with spaces)
FirstNameofStudent StudentID
School Name2 (with spaces)
FirstNameofStudent2 StudentID2
School Name3 (with spaces)
FirstNameofStudent3 StudentID3

I cant seem to figure out what to do after using fgets for the first line.

If by itself, I can easily get school name using fgets and the second line by itself using fscanf then converting the studentID to int using atoi .

But how do I combine both fgets and fscanf ?

The information scanned would be placed into an array.

Before I go onto the solution, I want to point out that an array can only have a single type. You cannot store integers in an array of characters.

Meaning if you would like all of this information to go in a single 2D array, you'd need to store the ID as a string. Then if you need it as an integer, you'd need to use atoi on it once you retrieve it.

Now for combining the two, you'd need a while loop with fgets in the condition in order to retrieve the first line. Something like this:

while(fgets(schoolname, 255, fp) != 0){ ... }

This would keep on retrieving lines until it fails, or it reaches EOF. However, you wanted to use fscanf for the second line, and for that, you'd need a line like this:

fscanf(fp, "%s %s\n", name, id);

This means, from the current point, there are two strings seperated by a space, and a newline. Store the two strings in name and id , and gobble the newline.

Gobbling the newline is key, as if you don't do it, the next time fgets runs, it would only find a single newline on the line.

As for storing the elements in an array, you'd need a 2D array of strings. For that, you can either do it fixed, or dynamic. For fixed, it's pretty easy, just have a line like char students[3][3][80] and simply store stuff in there, but for dynamic, you'd need to use memory allocation, pointers, etc, with a variable liks char ***students

Here's the code I used to solve your problem, though I suggest trying to do this on your own as well, to get the hang of it:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(){
    FILE *fp = fopen("ex.txt", "r");

    if(fp == 0) exit(-1);

    char ***students;

    // Used to check how many students there are
    int studentno = 0;

    // Init students array
    // So far it means 1 ROW, with 3 COLUMNS, each of 80 CHARACTERS
    students = calloc(studentno+1, 3 * 80);

    // Temporary variables for storage
    char schoolname[80];
    char name[20];
    char id[10];

    int i = 0;

    while(fgets(schoolname, 255, fp) != 0){
        studentno++;

        // Retrieve name and id from second line
        fscanf(fp, "%s %s\n", name, id);

        // Cut off newline left from fgets
        schoolname[strlen(schoolname)-2] = 0;

        // Allocate memory for new members of array
        students[i] = malloc(3 * 80);
        students[i][0] = malloc(80);
        students[i][1] = malloc(80);
        students[i][2] = malloc(80);

        // Copy strings received into array
        strcpy(students[i][0], schoolname);        
        strcpy(students[i][1], name);
        strcpy(students[i][2], id);

        // Resize students array for additional students
        students = realloc(students, (size_t) (studentno+1) * 3*80);

        i++;
    }

    // Check students are stored correctly
    for(int i = 0; i < studentno-1; i++){
        printf("%s - %s - %s\n", students[i][0], students[i][1], students[i][2]);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM