使用fscanf读取文本文件无法正常工作

时间:2019-10-16 21:01:52

标签: c scanf

我可以读取包含数字和som文本的文件,但是当我尝试读取文件的每一行时,它会跳过数字第一行之后的\ n,并且将两行读为一行而不是两行分开一个。

我想为此严格使用fgets和fscanf。

struct lakemedel
{
    char namn[MAXORD];
    int forpackningar[PAKETSTORLEKAR];
    int antalForpackningar;
    int saldo[PAKETSTORLEKAR];
    int antalSaldo;
};
typedef struct lakemedel Lakemedel;

Lakemedel lakemedelRegister[MAXANTAL];

    printf("Skriv in fil du vill anvanda: ");
    scanf(" %s", lasFilnamn);
    int i = 0;
    int f = 0;
    int s = 0;
    int nl = 0;
    FILE *fp;
    fp = fopen(lasFilnamn, "r");
    if(fp!=NULL)
    {        
        while(fscanf(fp,"%s", lasLakemedelRegister[i].namn)==1)
        {
            lasLakemedelRegister[i].antalForpackningar = 0;
            lasLakemedelRegister[i].antalSaldo = 0;
            printf("fff");
            while (fscanf(fp, "%d", &lasLakemedelRegister[i].forpackningar[lasLakemedelRegister[i].antalForpackningar]) == 1)
            {
                printf("aaa");
                lasLakemedelRegister[i].antalForpackningar++;                
            }
            while (fscanf(fp, "%d", &lasLakemedelRegister[i].saldo[lasLakemedelRegister[i].antalSaldo])==1)
            {
                lasLakemedelRegister[i].antalSaldo++;
            }
            /*for (lasLakemedelRegister[i].antalForpackningar = 0; lasLakemedelRegister[i].antalForpackningar == 1; lasLakemedelRegister[i].antalForpackningar++)
            {            
                fscanf(fp, "%d", &lasLakemedelRegister[i].forpackningar[lasLakemedelRegister[i].antalForpackningar]);
            }
            for (lasLakemedelRegister[i].antalSaldo = 0; lasLakemedelRegister[i].antalSaldo < PAKETSTORLEKAR; lasLakemedelRegister[i].antalSaldo++)
            {            
                fscanf(fp, "%d", &lasLakemedelRegister[i].saldo[lasLakemedelRegister[i].antalSaldo]);
            }*/
            (*pAntalLakemedel)++;
            i++;
        }

这是我想读取的文件的示例:

Hello
25 40
2 5
Hi
85 41
2 3

我希望每行如果将数字读入数组,但是之所以没有这样做,是因为它会以某种方式跳过换行符并读取到下一个文本行。

这是完整的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXANTAL 10000
#define MAXORD 20
#define PAKETSTORLEKAR 10
#define FILNAMNSTORLEK 20

struct lakemedel
{
    char namn[MAXORD];
    char forpackningar[PAKETSTORLEKAR];
    int antalForpackningar;
    char saldo[PAKETSTORLEKAR];
    int antalSaldo;
};
typedef struct lakemedel Lakemedel;

void lasFil(Lakemedel lasLakemedelRegister[], int *pAntalLakemedel, char lasFilnamn[]);
void skrivUt(Lakemedel skrivLakemedelRegister[], int pAntalLakemedel);

int main()
{
    Lakemedel lakemedelRegister[MAXANTAL];
    char filnamn[FILNAMNSTORLEK];
    int antalLakemedel = 0;
    int val;
    lasFil(lakemedelRegister, &antalLakemedel, filnamn);
    //printf("%d", lakemedelRegister[0].forpackningar[0]);
    while (1 && val != 8)
    {   
        printf("\n\n2-Skriva\n8-Avsluta\n\n");
        scanf(" %d", &val);
        switch (val)
        {
        case 1: //Registrera
            break;     
        case 2: //Skriva ut
            skrivUt(lakemedelRegister, antalLakemedel);
            break;
        case 3: //Söka
            break;
        case 4: //Lägga till storlek
            printf("hello");
            break;
        case 5: //Ändra saldo för läkemedel
            printf("hello");
            break;
        case 6: //Avregistrera läkemedel
            break;
        case 7: //Varningar
            printf("hello");
            break;
        case 8: //Avslutar programmet
            printf("Avslutar Programmet...");
            break;
        default:
            break;
        } 
    }

    return 0;
}

void lasFil(Lakemedel lasLakemedelRegister[], int *pAntalLakemedel, char lasFilnamn[])
{
    printf("Skriv in fil du vill anvanda: ");
    scanf(" %s", lasFilnamn);
    int i = 0;
    FILE *fp;
    fp = fopen(lasFilnamn, "r");
    if(fp!=NULL)
    {   
        while(fscanf(fp,"%s", lasLakemedelRegister[i].namn)==1)
        {
            lasLakemedelRegister[i].antalForpackningar = 0;
            lasLakemedelRegister[i].antalSaldo = 0;
            printf("ff");
            while (fscanf(fp, "%d", &lasLakemedelRegister[i].forpackningar[lasLakemedelRegister[i].antalForpackningar]) == 1)
            {
                printf("aa ");
                lasLakemedelRegister[i].antalForpackningar++;                
            }
            while (fscanf(fp, "%d", &lasLakemedelRegister[i].saldo[lasLakemedelRegister[i].antalSaldo])==1)
            {
                printf("gg ");
                lasLakemedelRegister[i].antalSaldo++;
            }
            /*for (lasLakemedelRegister[i].antalForpackningar = 0; lasLakemedelRegister[i].antalForpackningar == 1; lasLakemedelRegister[i].antalForpackningar++)
            {            
                fscanf(fp, "%d", &lasLakemedelRegister[i].forpackningar[lasLakemedelRegister[i].antalForpackningar]);
            }
            for (lasLakemedelRegister[i].antalSaldo = 0; lasLakemedelRegister[i].antalSaldo < PAKETSTORLEKAR; lasLakemedelRegister[i].antalSaldo++)
            {            
                fscanf(fp, "%d", &lasLakemedelRegister[i].saldo[lasLakemedelRegister[i].antalSaldo]);
            }*/
            (*pAntalLakemedel)++;
            i++;
        }
    fclose(fp);
    }
        printf("\n\n%d\n", *pAntalLakemedel);
        printf("%s\n",lasLakemedelRegister[0].namn);
        printf("%d\n",lasLakemedelRegister[0].antalForpackningar);
        printf("%d\n", lasLakemedelRegister[0].antalSaldo);
}

1 个答案:

答案 0 :(得分:0)

根据C标准,fscanf成功后将返回从输入流读取的项目数(如果发生读取错误或到达文件末尾,该数目可以小于请求的数目)。如果发生读取错误,或者在读取任何数据之前已到达文件末尾,则返回EOF。

因此,正如其他人所说的那样,以下while循环不会在换行符处停止。仅当输入流遇到非整数字符或达到EOF时,它才会停止。

while (fscanf(fp, "%d", &lasLakemedelRegister[i].forpackningar[lasLakemedelRegister[i].antalForpackningar]) == 1)
{
   printf("aa ");
   lasLakemedelRegister[i].antalForpackningar++;                
}

使用fscanf从输入流中读取两个数字的正确方法如下:

numIntsRead = fscanf(fp, " %d %d", &intVar1, &intVar2);
// Use numIntsRead to ensure both numbers were actually read

您可能希望删除两个while循环,而只需对上面要读取的每组2x int调用两次以上代码即可。

P.S。请注意格式说明符中的前导空格。按照标准,格式说明符中的空格可以与输入中的或更多空白字符匹配。如果文件中有前导空格,这将确保正确解析。