user6663837
user6663837

Reputation:

Reading input from file and store in an array in a particular format in C

I want to read from a text file and show some output

Input file format:

0 0 3         
0 1 2         
1 3 4         
2 1 4         
3 2 3         
3 1 2         
4 3 4      

1st digit of each line indicates a particular day (day 0 to 4) and the second and the 3rd digit of each line indicates actors who sends message to each other on that day. I have written the following c code to display the participating actor on each day:

My sample code:

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#define B 5 // number of days
#define A 5 // number of total actors

main()
{
    FILE *fp;
    int end = 0;
    int day1, day, i, j, k1, k2;
    int esin[A][A];
    for (i = 0; i < A; i++)  // initializing array
    {
        for (j = 0; j < A; j++)
        {
            esin[i][j] = 0;
        }
    }
    fp = fopen("test.txt", "r"); // the file contains the input
    if (fp == NULL)
    {
        printf("\nError - Cannot open the designated file\n");
    }

    while (end == 0)
    {
        fscanf(fp, "%d", &day);
        day1 = day; // day1 for comparing
        while (day1 == day)
        {
            if (feof(fp))
            {
                end = 1;
                break;
            }
            fscanf(fp, "%d %d", &k1, &k2);

            esin[k1][k2] = 1;// edge creation
            esin[k2][k1] = 1;// edge creation

            fscanf(fp, "%d", &day);
        }

        printf("\nday: %d", day1); // for printing output of a particular day
        for (i = 0; i < A; i++)
        {
            for (j = 0; j < A; j++)
            {
                if (esin[i][j] == 0)
                    continue;
                else
                    printf("\n%d and %d have an edge", i, j);
            }
        }
        for (i = 0; i < A; i++)
        {
            for (j = 0; j < A; j++)
            {
                esin[i][j] = 0;
            }
        }
    }
}

But I am not getting the actual output. For example, I want to get an output like:

day 0
0 and 3 have an edge
1 and 2 have an edge
day 1
3 and 4 have an edge
day 2
1 and 4 have an edge
day 3
2 and 3 have an edge
1 and 2 have an edge
day 4
3 and 4 have an edge

But I am not getting this. I am getting:

day 0
0 and 3 have an edge
1 and 2 have an edge
day 3
4 and 2 have an edge
day 4
3 and 2 have an edge
day 3
1 and 2 have an edge
day 3
4 and 2 have an edge

Is there anything wrong in the above code? Which correction will I need to make to get the above like output?

Upvotes: 1

Views: 64

Answers (4)

pPanda_beta
pPanda_beta

Reputation: 648

If you are only interested in printing the input in pretty English [in the same order of the input file]

This smallified code will do so :

#include <stdio.h>
#include <stdlib.h>
#define B 5 // number of days
#define A 5 // number of total actors

int main()
{
    int day1=-1, day, k1, k2;

    FILE *fp= fopen("test.txt", "r"); // the file contains the input
    if (fp == NULL)
    {
        printf("\nError - Cannot open the designated file\n");
        return 0;
    }
    
    while(fscanf(fp,"%d%d%d",&day,&k1,&k2)>0)
    {
        if(day1!=day || day1==-1 )
            printf("\nday: %d", day1=day); 
        printf("\n%d and %d have an edge", k1,k2);
    }
    
    return 0;
}

Buttttt if u really want to store the input for each days and then print it in a lexicographical manner [ASCENDING ORDER OF ACTOR NO] then here is ur modified code :

#include <stdio.h>
#include <stdlib.h>
#define B 5 // number of days
#define A 5 // number of total actors

int main()
{
    int day1=-1, day, i, j, k1, k2;
    int esin[A][A]={0};

    FILE *fp= fopen("test.txt", "r"); // the file contains the input
    if (fp == NULL)
    {
        printf("\nError - Cannot open the designated file\n");
        return 0;
    }
    
    while(!feof(fp))
    {
        if( fscanf(fp,"%d%d%d",&day,&k1,&k2)<0  || (day1!=-1 && day1!=day ))
        {
            printf("\nday: %d", day1<0?day:day1); 
            for(i=0;i<A;i++)
                for(j=0;j<A;esin[i][j]=0,j++)
                    if(esin[i][j])
                        printf("\n%d and %d have an edge", i, j);   
            esin[k1][k2]=1;
            day1=day;
        }
        if(day1==-1)
            day1=day;
        esin[k1][k2]=1;
    }
    
    return 0;   
}

Key Points to remember (also mentioned above in comments) :

  1. scanf family (scanf,fscanf,...) returns -1 on reaching of EOF.
  2. scanf family returns the no of successfully scanned variables.
  3. No explicit reset or initialize to zero is required. Member initializer {0} OR the printing nested for loop for(j=0;j<A;esin[i][j]=0,j++)can do so.
  4. -1 is considered as an invalid day.
  5. if(esin[i][j]) means if(esin[i][j]!=0) i.e. actor i messages actor j.

Upvotes: 1

Rajmani Arya
Rajmani Arya

Reputation: 104

Here you are scanning one date from input and checking against first integer (which is date) for each next line, when day1 != day your inner loop won't execute but you already read that day value. now when you perform fscanf(fp, "%d", &day) on input it will read person id (2nd column) and it totally get messed up.

I would suggest to do one time file scanning and build graph

int a,b;
for (int i=0; i<5; i++)
for (int j=0; j<5; j++) 
     esin[i][j] = -1; // No edge
while (!feof(fp)) {
     fscanf(fp, "%d %d %d", &day, &a, &b);
     esin[a][b] = day;
     esin[b][a] = day;
}

// for each day find person1,person2
for (int i=0; i<5; i++) {
    printf("Day %d:\n", i);
    for (int p=0; p<5; p++) {
        for (int q=0; q<5; q++) {
            if(esin[p][q] == i) {
                printf ("%d and %d have an edge\n", p, q);
            }
        }
    }
}

Upvotes: 1

Shahid
Shahid

Reputation: 2330

  1. Change if(esin[i][j]=0) to if(esin[i][j]==0).

  2. If you do:

        esin[k1][k2] = 1;
        esin[k2][k1] = 1;
    

Output will be for day-0:

day: 0 
0 and 3 have an edge 
1 and 2 have an edge 
2 and 1 have an edge
3 and 0 have an edge

Just do esin[k1][k2] = 1; if you want output like:

day: 0 
0 and 3 have an edge 
1 and 2 have an edge 
  1. And another issue is, day is being scanned twice when day is changing (One inside while(day1 == day) loop and another outside this loop). You can try this:
bool first = true; 

while(end==0)
{
    // Only first time we'll read 'day', 
    // later we won't need this fscanf since there is another fscanf for reading day
    if(first)
    {
        fscanf(fp, "%d", &day);    
    }
    day1 = day; //day1 for comparing
    first = false;    

    while(day1 == day)
    {
        if (feof(fp))
        {
            end=1;
            break;
        }

        fscanf(fp, "%d %d", &k1, &k2);
        esin[k1][k2] = 1;//edge creation
        fscanf(fp, "%d", &day);
    }
    ...
}

Upvotes: 1

David Ranieri
David Ranieri

Reputation: 41017

In this line

if(esin[i][j]=0)

you are assigning, but you want to compare:

if(esin[i][j] == 0)

Upvotes: 1

Related Questions