卡住循环,应该在文件结束后停止 - C

问题描述:

我似乎无法弄清楚如何修复我的循环在main中,以便它在文件结束时停止。我认为通过从我的扫描函数返回一个值,它会导致循环停止在文件的末尾。看来变量结果没有被返回。卡住循环,应该在文件结束后停止 - C

可能有另一种循环两个函数调用的方法,以便它们在文件结束时停止?

有一个注释掉的部分直到文件结束,但我试图使用已创建的打印和扫描功能来完成此操作。

代码到目前为止....

#include <stdio.h> 

#define STRSIZE 20 

/* Structure definitions */ 
typedef struct { 
     int  month, 
       day, 
       year; 
} date_t; 

typedef struct { 
     double capacity, 
       current; 
} tank_t; 

typedef struct { 
     char make[STRSIZE], 
       model[STRSIZE]; 
     int  odometer; 
     date_t manuf, 
       purch; 
     tank_t tank; 
} auto_t; 

/* Function prototypes */ 



int scan_date(date_t *date, FILE *inp); 
int scan_tank(tank_t *tank, FILE *inp); 
int scan_auto(auto_t *vehicle, FILE *inp); 


void print_date(date_t date); 
void print_tank(tank_t tank); 
void print_auto(auto_t vehicle); 

int main() 
{ 
    auto_t  vehicle; 
    date_t  date; 
    tank_t  tank; 
    int   i=0, 
       result=1; 

    FILE *inp = fopen("autos.txt","r");    /* defining file input */ 

    /* Check to make sure input file is found and readable. */ 
    if(inp==NULL){ 
     printf("Error: Input file - autos.txt - not found!\n"); 

     getch(); 
     return 0; 
    } 

    printf("Vehicle Vehicle Odometer Date  Date   Tank  Current\n"); 
    printf("Make  Model Reading Purchased Manufactured Capacity Fuel Level\n"); 
    printf("\n----------------------------------------------------------------------------\n"); 


/*******************COMMENTED OUT************************************* 
    while(status>0){ 
     status=fscanf(inp, "%s%s%d%d%d%d%d%d%d%lf%lf", vehicle.make, 
                 vehicle.model, 
                 &vehicle.odometer, 
                 &vehicle.manuf.month, 
                 &vehicle.manuf.day, 
                 &vehicle.manuf.year, 
                 &vehicle.purch.month, 
                 &vehicle.purch.day, 
                 &vehicle.purch.year, 
                 &vehicle.tank.capacity, 
                 &vehicle.tank.current); 

    if(status==11){ 
     printf("%-10s%-9s%-10d%2d/%d/%-6d%2d/%d/%-8d%-11.1lf%.1lf\n", vehicle.make, 
                    vehicle.model, 
                    vehicle.odometer, 
                    vehicle.manuf.month, 
                    vehicle.manuf.day, 
                    vehicle.manuf.year, 
                    vehicle.purch.month, 
                    vehicle.purch.day, 
                    vehicle.purch.year, 
                    vehicle.tank.capacity, 
                    vehicle.tank.current); 
     i++;} 

    else if(status <11 && status>0){ 
     printf("\nInvalid Input - The next line of data is corrupt.\n"); 
    }            
    }             
******************************************************************************/ 


    while(result>0){ 

     scan_auto(&vehicle, inp); 

     if(result==11){ 

      print_auto(vehicle); 
     } 

     else if(result <11 && result>0){ 

      printf("\nInvalid Input - The next line of data is corrupt.\n"); 
     }            
    } 

    getch(); 
    return 0; 
} 

/*********************************************************************************/ 
int scan_date(date_t *date, FILE *inp) 
{ 
    int result = fscanf(
     inp, 
     "%d%d%d", 
     &(date->day), 
     &(date->month), 
     &(date->year)); 

    return (result == 3); 
} 

/*********************************************************************************/ 
int scan_tank(tank_t *tank, FILE *inp) 
{ 
    int result = fscanf(
     inp, 
     "%lf%lf", 
     &(tank->capacity), 
     &(tank->current)); 


    return (result == 2); 

} 

/*********************************************************************************/ 
int scan_auto(auto_t *vehicle, FILE *inp) 
{ 
    int result = fscanf(
     inp, 
     "%s%s%d", 
     vehicle->make, 
     vehicle->model, 
     &(vehicle->odometer)); 

    result += scan_date(&(vehicle->purch), inp); 
    result += scan_date(&(vehicle->manuf), inp); 
    result += scan_tank(&(vehicle->tank), inp); 

    return (result = 11); 
} 
/*********************************************************************************/ 
void print_auto(auto_t vehicle) 
{ 
    printf("\n%-10s%-9s%-10d", vehicle.make, 
          vehicle.model, 
          vehicle.odometer); 
    print_date(vehicle.purch); 
    print_date(vehicle.manuf); 
    print_tank(vehicle.tank); 



} 

/*********************************************************************************/ 

void print_date(date_t date) 
{ 
    printf("%1d/%d/%-7d", date.day, 
          date.month, 
          date.year); 

}  

/*********************************************************************************/ 

void print_tank(tank_t tank) 
{ 
     printf(" %-11.1lf%.1lf", tank.capacity, 
           tank.current); 

} 

这里是它采用了autos.txt文件....

Mercury  Sable 99842 1 18 2001 5 30 1991 16 12.5 
Mazda  Navajo 123961 2 20 1993 6 15 1993 19.3 16.7 
Ford 

我在那里留下了一个额外的名称,触发用户检查文件以确保其完整的错误消息。

+1

在'main()'中,'result'被初始化为'1' - 并且**从不**改变。 –

您没有使用scan_auto的返回值。你可能想:

result = scan_auto(&vehicle, int); 

另外,您的每一个scan_函数应返回找到的字段数。而不是像return (result == 3);只是return result

+0

我认为这是一种自我测试。 'return(result == 3);'返回1或0,取决于是否读取了正确的数量。他只需在每个函数调用返回时测试true或false,并将'return(result = 11);'改为'return(result == 11);' – Unimportant

+0

也许 - 当然,代码真的很混乱。由于'scan_auto'增加了'scan_date'和'scan_tank'的返回值,并且主循环试图检查总值,看起来他似乎正在计算读取的字段数。 –

+0

我正在尝试计算已读取的字段,但我发现这不起作用。我试图找到一种方式来循环它而不使用fscanf。 – codeRed

立即问题很简单:

int result = 1; 
while(result>0){ 
    scan_auto(&vehicle, inp); 
    if(result==11){ 
     print_auto(vehicle); 
    } 
    else if(result <11 && result>0){ 
     printf("\nInvalid Input - The next line of data is corrupt.\n"); 
    }            
} 

没有分配给result内环路,因此该循环永远不会终止。您应该看到“无效的输入”无限触发printf

而现在一个忠告:用C解析文本输入,作为一般规则,最好fscanf完成,原因全过多 - 我对这种文本文件的通常的建议是

  • getline如果可用,否则fgets,在一次
  • strtok阅读整行每行拆分成田
  • strtolstrtod等转换成十进制数加工整数和浮游物。