Reputation:
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
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;
}
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.if(esin[i][j])
means if(esin[i][j]!=0)
i.e. actor i
messages actor j
.Upvotes: 1
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
Reputation: 2330
Change if(esin[i][j]=0)
to if(esin[i][j]==0)
.
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
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
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