简体   繁体   中英

fscanf a line from file in c

I have a file that i need to read from into certain variables. The information is stored in the file with a delimiter ; that separates between each bit of information. for example:

308163583 ;Adam ;Fro ;22;M ;mogar ;mmMM8675 ;like to walk on the beach ;1,2,3,4;

afterwards i'm going to place that information into a structure but that's not relevant now. the problem is that it scans everything fine until "like to walk on the beach" and it stops at "like" and only scans this word into description string

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXID 10
#define MAXN 11
#define MAXPAS 7
#define MAXDES 201
#define MAXHOB 4
#define MAXGEN 2
typedef enum { false, true } bool;
typedef struct {

    char* id;
    char* fname;
    char* lname;
    int age;
    char* gender;
    char* username;
    char* password;
    char* description;
    int hobbies;
}User;
typedef struct {
    User *users;
    int num_users;
}List;

void inputFunction(FILE *ifp);
void main() {
    FILE *ifp;
    char mode[] = "r";
    ifp = fopen("input.txt", mode);
    if (ifp == NULL) {
        puts("Can't open input file");
        exit(1);
    }
    inputFunction(ifp);
}

void inputFunction(FILE *ifp) {
    List userList;
    userList.users = (User*)malloc(1 * sizeof(User));
    int i = 0;
    char id[MAXID], fname[MAXN], lname[MAXN], gender[MAXGEN],
       username[MAXN], password[MAXPAS], description[MAXDES];
    int age, hobbies[MAXHOB];
    while (fscanf(ifp, "%s ;%s ;%s ;%d;%s ;%s ;%s ;%s;%d,%d,%d,%d", id,
      fname, lname, &age, gender, username, password, description,
      &hobbies[0], &hobbies[1], &hobbies[2], &hobbies[3])!=EOF)
    {

    }
}

That's because scanf's %s is specified as Matching a sequence of non-white-space characters . You want it to scanf for a sequence of non-semicolon characters . Left as an exercise :-) Hint: read the manual and see how the %[...] specifier works.

Also note that

while (fscanf(...) != EOF)

is a colossal bug, since fscanf returns the number of successfully converted items, ie 0 if nothing was converted and 12 if all items were converted. Testing for EOF you can't detect if less than 12 items where correctly converted. You should seriously consider reading the scanf/fscanf manual from top to bottom. It is quite instructive and will prove valuable time and again over your whole programming career.

You could use the strtok function to split the line using your own set of delimiters.

/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
    const char delims[] = ";"; //List of delimiters
    char str[] = "308163583 ;Adam ;Fro ;22;M ;mogar ;mmMM8675 ;like to walk on the beach ;1,2,3,4;";
    char * pch;
    // Split the string at specified set of delimters
    pch = strtok (str,delims);
    while (pch != NULL)
    {
        // Do whatever you need to process the token here
        printf ("%s\n",pch);

        // Find the next token
        pch = strtok (NULL,delims);
    }
    return 0;
}

Normally, scanf() function read the string up to the white space character only. You should try with strtok() function for getting the stream up to the specified delimiter.

@Jens: For the current assignment I don't require checking that all fields are correct, it is given. Found a different solution:

List loadFile(FILE *ifp) {
    int i = 0;
    List userList;
    userList.users = NULL;
    char id[MAXID], fname[MAXN], lname[MAXN], gender[MAXGEN], username[MAXN], password[MAXDES], description[MAXDES];
    int age, hobbies[MAXHOB];
    while (fscanf(ifp, "%s ;%s ;%s ;%d;%s ;%s ;%s ;%200[^;];%d,%d,%d,%d;\n", id, fname, lname, &age, gender, username, password, description, &hobbies[0], &hobbies[1], &hobbies[2], &hobbies[3]) != EOF)
    {

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