Gur
Gur

Reputation: 111

how to read a specific format using fscanf in c

I have a text file of lines. each line starts with a 30 characters of name, then 9 digits for id1, 9 digits for id2 then 1 line for operation type.

example: abcdefghijklmnopqrstuvwxyzabcd3003003002002002001

can someone help me with the format needed to be used to read it into a structure?

thanks

Upvotes: 1

Views: 81

Answers (3)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

It could look like this:

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

int main() {
    char s[] = "abcdefghijklmnopqrstuvwxyzabcd3003003002002002001\n";
    char name[31];
    int id1;
    int id2;
    int operation;
    if(sscanf(s, "%30c%9d%9d%d\n", name, &id1, &id2, &operation) == 4) {
        // or " %30c%9d%9d%d"
        printf("%s (%zu)\n", name, strlen(name));
        printf("%d\n", id1);
        printf("%d\n", id2);
        printf("%d\n", operation);
    }
}

Output:

abcdefghijklmnopqrstuvwxyzabcd (30)
300300300
200200200
1

With a struct to keep the data together and some helper functions:

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

typedef struct {
    char name[31];
    int id1;
    int id2;
    int operation;
} foo_t;

/* read one line from a stream into a "foo_t" */
bool foo_t_read(FILE* fp, foo_t* f) {
    return fscanf(fp, " %30c%9d%9d%d", 
                  f->name, &f->id1, &f->id2, &f->operation) == 4;
}

/* print the values in a "foo_t" to a stream */
FILE* foo_t_print(FILE* fp, const foo_t* f) {
    fprintf(fp,
            "%s\n"
            "%d\n"
            "%d\n"
            "%d\n",
            f->name, f->id1, f->id2, f->operation);
    return fp;
}

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

    if(fp) {
        foo_t foo;
        while(foo_t_read(fp, &foo)) {
            foo_t_print(stdout, &foo);
        }
        fclose(fp);
    }
}

Upvotes: 3

Papai from BEKOAIL
Papai from BEKOAIL

Reputation: 1529

you use can following code for your purpose:

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

int main () {
 char str1[30];
 int id1, id2, opType;
 FILE * fp;

 fp = fopen ("test.txt", "w+");
 fputs("abcdefghijklmnopqrstuvwxyzabcd3003003002002002001\n", fp);

 rewind(fp);
 fscanf(fp, "%30c%9d%9d%d", str1, &id1, &id2, &opType);

 printf("Read String1 |%s|\n", str1 );
 printf("Read ID_1 |%d|\n", id1);
 printf("Read ID_2 |%d|\n", id2);
 printf("Read Operation Type |%d|\n", opType);

 fclose(fp);

 return(0);
}

NOTE

rewind: function lets the file position to the beginning of the file, for the stream pointed by stream.

Output:

Read String1 |abcdefghijklmnopqrstuvwxyzabcd|
Read ID_1 |300300300|
Read ID_2 |200200200|
Read Operation Type |1|

Upvotes: -1

Nikola Lukic
Nikola Lukic

Reputation: 4244

I use code from @Ted Lyngmo and add it with read line by line :

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

int main(void)
{
    FILE * fp;
    char * line = NULL;
    size_t len = 0;
    ssize_t read;

    fp = fopen("a.txt", "r");
    if (fp == NULL)
        exit(EXIT_FAILURE);

    while ((read = getline(&line, &len, fp)) != -1) {
        printf("Retrieved line of length %zu:\n", read);
        printf("%s", line);

        char name[31];
        int id1;
        int id2;
        int operation;

      if(sscanf(line, "%30c%9d%9d%d", name, &id1, &id2, &operation) == 4) {
        printf("%s (%d)\n", name, strlen(name));
        printf("id1 => %d\n", id1);
        printf("id2 =>%d\n", id2);
        printf("operation => %d\n", operation);
      }
    }

    fclose(fp);
    if (line)
        free(line);
    exit(EXIT_SUCCESS);
}

Upvotes: 1

Related Questions