繁体   English   中英

从文件读取输入并以C的特定格式存储在数组中

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

我想从文本文件中读取并显示一些输出

输入文件格式:

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

每行的第一位数字表示特定的一天(第0天到第4天),每行的第二位和第三位数字表示当天发送信息的演员。 我编写了以下c代码来每天显示参与的演员:

我的示例代码:

#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;
            }
        }
    }
}

但是我没有得到实际的输出。 例如,我想获得类似以下的输出:

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

但是我不明白这一点。 我正进入(状态:

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

上面的代码有什么问题吗? 我需要进行哪些更正才能获得上述类似的输出?

在这条线

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

您正在分配,但您想比较:

if(esin[i][j] == 0)
  1. if(esin[i][j]=0)更改为if(esin[i][j]==0)

  2. 如果您这样做:

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

输出将是第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

只是做esin[k1][k2] = 1; 如果要输出如下:

day: 0 
0 and 3 have an edge 
1 and 2 have an edge 
  1. 另一个问题是, 当日期更改时一天要扫描两次 (一个在while(day1 == day)循环内,另一个在该循环外)。 您可以尝试以下方法:
 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); } ... } 

在这里,您将从输入中扫描一个日期,并针对下一行的第一个整数(即日期)进行检查,当day1!= day时,您的内部循环将不会执行,但您已经读取了该天的值。 现在,当您在输入上执行fscanf(fp,“%d”,&day)时,它将读取人员ID(第二列),并且完全搞砸了。

我建议做一次文件扫描并建立图形

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);
            }
        }
    }
}

您可以投反对票,但我要求您发表评论,以便我改善此答案的质量

如果您只想用漂亮的英语打印输入内容[与输入文件的顺序相同]

这个简化的代码将这样做:

#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如果您真的要存储每一天的输入,然后以字典方式[ACTOR NO.ASCENDING ORDER NO。]进行打印,则这里是经过修改的代码:

#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;   
}

要记住的关键点(也在上面的评论中提到):

  1. 在到达EOF时,scanf系列(scanf,fscanf,...)返回-1。
  2. scanf系列返回未成功扫描的变量的编号。
  3. 无需显式resetinitialize to zero 成员初始化程序{0}或嵌套for for(j=0;j<A;esin[i][j]=0,j++)循环的打印都可以这样做。
  4. -1被认为是无效的一天。
  5. if(esin[i][j])是指if(esin[i][j]!=0)即演员i消息演员j

PS编写短代码是一种好习惯,但令人毛骨悚然的代码不是...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM