陷入循环,应该在文件结束后停止 - C

时间:2016-04-24 22:11:57

标签: c structure scanf

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

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

有一个注释掉的部分会一直读到文件末尾,但我正在尝试使用已创建的打印和扫描功能完成此操作。

到目前为止

代码......

#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

我在那里留下了一个额外的名字,以便触发一条错误信息,让用户检查文件以确保文件完整。

2 个答案:

答案 0 :(得分:1)

您的立即问题非常简单:

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的赋值,因此循环永远不会终止。您应该看到&#34;无效输入&#34; printf无休止地触发。

现在提出一条建议:解析用C语言输入文本作为一般规则,最好用fscanf完成,原因很多 - 我通常的建议是这种文本文件是

  • getline如果可用,否则fgets,一次读取整行
  • strtok将每一行拆分为字段
  • strtolstrtod等将十进制数转换为机器整数和浮点数。

答案 1 :(得分:0)

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

result = scan_auto(&vehicle, int);

此外,您的每个scan_函数都应返回找到的字段数。而不仅仅是return (result == 3); return result