0

I have to parse a text file with 3 different data types. I want it to be saved in a structure array with three members. My text file look like this:

A B 45.78965
A C 35.46731
B C 46.78695

The program that I'm reading it with is the following and it does not work. What am I doing wrong?

#include <stdio.h>

struct gra {
    char from;
    char to;
    double w;
};

int main ()
{
    FILE *fp = fopen("graph.txt", "r"); 
    int i = 0;
    while (!feof(fp)) {
        fscanf(fp, "%[^\t]", &graph[i].from, &graph[i].to, &graph[i].w);
        i++;
    }
    fclose(fp);
 }
nickie
  • 5,608
  • 2
  • 23
  • 37
Aq Toh
  • 13
  • 2

1 Answers1

2

One of your problems is that you're reading using %[^\t], which reads strings, and store the result to variables that are not character arrays (two characters and a double).

Although it's not clear from your question, it seems that the lines of your input contain two characters and one real number separated by one tab character. If that is so, you should use the following fscanf to read them:

fscanf(fp, "%c\t%c\t%lf\n", &graph[i].from, &graph[i].to, &graph[i].w);

If you are not sure what exactly separates your fields and you want to allow any amount of white space in between and also extra white space in the beginning and end of the line, then use:

fscanf(fp, " %c %c%lf\n", &graph[i].from, &graph[i].to, &graph[i].w);

that is, use an extra space in the format before each "%c" to explicitly skip white space.

Your code has also a couple of other problems:

  1. You are using feof to check for end of file. This will usually not work well if you're not reading the file character by character. Instead, you should check if your fscanf returned 3, that is, if it successfully read the three things that you wanted it to read.

  2. You are missing a definition of array graph.

I'm adding the complete code that I'd write for doing the parsing:

#include"stdio.h"
#define MAX 100

struct {
  char from, to;
  double w;
} graph[MAX];

int main ()
{
  FILE *fp = fopen("graph.txt", "rt");  
  for (int i=0; i<MAX; i++)
    if (fscanf(fp, " %c %c%lf\n", &graph[i].from, &graph[i].to, &graph[i].w) < 3)
      break;
  fclose(fp);
  return 0;
}
nickie
  • 5,608
  • 2
  • 23
  • 37
  • Yes thank you for the comments. My question is how can I save those data types into the structure array? I can print the data using the function printf("%c %c %lf",a.from,a.to,a.w) but i can't save those data into my array. should I use fget function to reading every single character in the text file? – Aq Toh Oct 03 '13 at 07:26
  • You will be saving your data to your array if you use a proper `fscanf`. I'm adding the complete code to my answer, to help you. – nickie Oct 03 '13 at 07:28
  • +1 for the sample code. – fkl Oct 03 '13 at 07:37
  • sorry last question. what is the meaning of "rt" in the code? and why did you use 3 in fscanf? :D thank you so much! :D – Aq Toh Oct 03 '13 at 12:23
  • The "rt" denotes that it is a text file (e.g. Automatically converts newlines between different OSs). You should use it when you know that your files contain text. – nickie Oct 03 '13 at 13:26
  • The magic number 3 is already explained in the answer: "Instead, you should check if your fscanf returned 3, that is, if it successfully read the three things that you wanted it to read." Check the returned value in the man page of scanf for more. – nickie Oct 03 '13 at 13:27