无法让我的程序加载文本文件

时间:2017-04-24 21:29:30

标签: c

所以我正在创建一个程序(试图)给用户一个菜单,允许你创建一个项目,修改一个项目,查看所有项目,然后显示一个项目然后选择0(退出)之前关闭程序,它将文件保存为文本,我试图在程序启动之前重新加载它,但是当我查看它时,它没有显示我上次打开程序时创建的内容。

需要它在首次退出程序时创建的文本中加载已保存的数据。任何关于我做错事的想法。

#include <stdio.h>
#include <stdlib.h>
#define MAX 12


//Structed Items

    struct item{

    char itemname[20];
    char itemdes[30];
    int itemID;
    int itemOH;
    double itemUP;
    };


// Function Declarations

    int getMenu_Choice ();
    int process (int choice, int count, struct item inven[]);
    int add (int count, struct item inven[]);
    int showall(int count, struct item inven[]);
    int find(int count, struct item inven[]);
    int modify(int count, struct item *inven);
    int save(int count, struct item inven[]);
    int load(int count, struct item inven[]);



int main (void)
{ // OPENS MAIN


//  Declarations

    int choice;
    struct item inven[MAX];
    int count = 0;


// Statements



do//
{   load (count, inven);
    choice = getMenu_Choice ();
    count = process (choice, count, &inven[0]);
}
while (choice != 0);

save (count, inven);

return 0;


} // CLOSE MAIN

/*============================getChoice=*/

int getMenu_Choice (void)
{ //OPEN GETCHOICE


// Declarations
    int choice;

// Statements

    printf("\n\n**********************************");
    printf("\n              MENU             ");
    printf("\n\t1.Add New Item To Inventory       ");
    printf("\n\t2.View All Items In Inventory          ");
    printf("\n\t3.Find An Item           ");
    printf("\n\t4.Search And Modify An Item");
    printf("\n\t0.Exit                    ");
    printf("\n**********************************");
    printf("\nPlease Type Your Choice Using 0-4");
    printf("\nThen Hit Enter: ");
    scanf("%d", &choice);

return choice;

} //CLOSES GET CHOICE




/*============================process=*/

int process (int choice, int count, struct item *inven)
{// OPEN PROCESS 


// Declarations


// Statements
    switch(choice)
        {
            case 1: count = add(count, inven);
                break;
            case 2: showall(count, inven);
                break;
            case 3: find(count, inven);
                break;
        case 4: modify(count, inven);
        break;
            case 0: exit;
                break;
            default: printf("Sorry Option Not Offered");
                break;

} // switch

return count;

} // CLOSE PROCESS


/*============================add one=*/
int add(int count, struct item *inven)

{//OPENS CREATE

// Declarations

    int i;


i = count;

if (i < MAX) 
{
    printf("Enter the Item ID:\n");
    scanf("%d", &inven[i].itemID);

    printf("Enter the Item Name:\n");
    scanf("%s", inven[i].itemname);
i++;

    }

else {
    printf("sorry there is no more room for you to add");

};

return i;


}; // CLOSE CREATE



/*============================showall=*/

int showall(int count, struct item *inven)
{
//Declarations
    int i;

// Statements




    for(i = 0; i < count; i++)
    {
    printf("\nItem ID   : %d", inven[i].itemID);
    printf("\nItem Name  : %s", inven[i].itemname);
    };    

return 0;
};

/*============================find one=*/

int find(int count, struct item *inven)
{

//Declarations 

    int i;
    int search;
    int found;

   printf("Enter the Item ID to search\n");
   scanf("%d", &search);
   for (i = 0; i < count; i++)
   {

    if(inven[i].itemID == search)

        {
          printf("\nItem ID   : %d", inven[i].itemID);
          printf("\nItem Name  : %s", inven[i].itemname);
      found = 1;
          break;
}


}

if(i == count) /* Will be true if the loop executed without executing the break */
{
    printf("\nSorry None existent");
};



return 0;
};

/*============================modify=*/
int modify(int count, struct item *inven)
//Declarations 
{

    int i;
    int search;
    int found;
    int choice;

   printf("Enter the Item ID to search\n");
   scanf("%d", &search);
   for (i = 0; i < count; i++)
   {

    if(inven[i].itemID == search)

        {
          printf("\nItem ID   : %d", inven[i].itemID);
          printf("\nItem Name  : %s", inven[i].itemname);
      found = 1;
      printf("\n\n        ****Modify Menu for %s*****", inven[i].itemname);
      printf("\n\n    Select a Number To Modify or 0 To Exit");
      printf("\n    =========================================");
      printf("\n    1. Item ID Number");
      printf("\n    2. Item Name"); 
      printf("\n                              Enter 0-2: ");
      scanf("%d", &choice); 


    switch(choice)
        {
            case 1: 
            printf("\nCurrent Item ID Number: %d", inven[i].itemID);
            printf("\nPlease Enter The New Item ID Number: ");
            scanf("%d", &inven[i].itemID);
            printf("\nNew Item ID: %d", inven[i].itemID);
                    break;

        case 2: 
            printf("\nCurrent Item Name: %s", inven[i].itemname);
            printf("\nPlease Enter The New Item Name: ");
            scanf("%s", &inven[i].itemname);
            printf("\nNew Item Name: %s", inven[i].itemname);
                    break;

            case 0: getMenu_Choice ();
                break;
            default: printf("Sorry Option Not Offered");
                break;

} // switch



          break;
}


}

if(i == count)
{
    printf("\nSorry Non existent");
};



return 0;
};


/*============================Save=*/
int save(int count, struct item inven[])
{

//Declarations
    int i; 
    FILE *fptr; 


//Statements


fptr = fopen("inven.txt", "w");

for(i = 0; i < count; i++)
{
fprintf(fptr, "ID = %d\n", inven[i].itemID);
fprintf(fptr, "Name = %s\n", inven[i].itemname);
};
fclose(fptr);

return 0;

};

/*============================Load=*/
int load(int count, struct item inven[])
{

//Declarations 
    FILE *fptr; 
    int i;


    count = 0;

    fptr = fopen("inven.txt", "r");

    for (i = 0; i < count; i++)
    {
        fscanf(fptr, "%d %s", &inven[i].itemID, &inven[i].itemname);
    }


    fclose(fptr);

return count;
};

3 个答案:

答案 0 :(得分:0)

此代码存在一些严重问题。如果这是生产代码,我建议您使用更适合文本处理的更宽容的语言来编写它。

我将尝试涵盖基础知识。

必须检查每个文件操作,否则你会想到什么是默默无闻的。它通常是这样的。

#include <string.h> // for strerror()
#include <stdlib.h> // for exit()
#include <errno.h>  // for errno

const char filename[] = "invent.txt";
fptr = fopen(filename, "r");
if( fptr == NULL ) {
    fprintf( stderr, "Couldn't open %s for reading: %s\n", filename, strerror(errno) );
    exit(1);
}

errno是一个全局变量,包含最后一个文件操作的错误代码。 strerror(errno)将其变成人类可读的东西。

然后你有这个for循环。

for (i = 0; i < count; i++)
{
    fscanf(fptr, "%d %s", &inven[i].itemID, &inven[i].itemname);
}

但是你设置count = 0;所以它永远不会运行。您还在main中传入了0,因此无论如何它都不会运行。

您也没有检查fscanf是否成功,所以如果该行与该格式不匹配,它会一次又一次地悄悄地重新扫描它。

您正在传递&inven[i].itemname,但inven[i].itemname已经是char *指针。与int字段不同,不需要获取它的地址。你应该只通过inven[i].itemname。你在其他地方犯了这个错误,应该对此发出警告。如果没有,请检查是否有编译器警告。

inven[i].itemname只有20个字符长,很容易溢出缓冲区。 %s应始终具有与之关联的大小,例如%19s(空字节为19 + 1为20)。

最后,fscanf should be avoided

相反,我建议你这样做。

int load(const char filename[], struct item inven[], size_t max_items) {
    // Open the file with error checking.
    FILE *fptr = fopen(filename, "r");
    if( fptr == NULL ) {
        fprintf( stderr, "Couldn't open %s for reading: %s\n", filename, strerror(errno) );
        exit(1);
    }

    // A buffer to read each line from the file
    char line[1024];

    // The number of items read.
    int num_items = 0;

    // Read each line
    while( (fgets( line, 1024, fptr ) != NULL) ) {
        // Don't walk off the end of the array.
        // Let the user know you had to stop early.
        if( num_items >= max_items ) {
            fprintf( stderr, "There were more lines than space to store them" );
            break;
        }

        // Parse the line, warn if we can't understand it.
        if( sscanf(line, "%d %19s", &inven[num_items].itemID, inven[num_items].itemname) != 2 ) {
            fprintf( stderr, "Could not understand '%s'\nSkipping.\n", line );
            continue;
        }

        num_items++;
    }

    fclose(fptr);

    return num_items;
}

然后就这样调用:

int num_items = load("inven.txt", inven, MAX);

传入文件名使功能更加灵活。由于您传入已分配的列表,因此该列表的大小也必须传入,否则该函数不知道何时停止写入列表。调用代码需要知道已填充inven的大小,即num_items

这只会让load正常工作,但其余的代码对于单个答案来说也有类似的问题。不要编写所有内容并尝试使其正常工作,而是尝试只编写load并让load正常工作。当它工作时,转到另一个功能。

另外需要注意的是,使用固定大小的数组和固定大小的字符串来处理数据文件并不会很好。您的字符串可能太小,而且您没有跟踪数组的长度。这一切都变得非常复杂。

相反,我建议您查看GLib,其中arraysstrings可以根据需要增长。他们也为你追踪他们的长度。

但实际上我建议用Ruby或Python等语言重写它,更适合文本处理,并为你处理内存管理。

答案 1 :(得分:0)

发布的load()函数存在很多问题。

请查看有关问题列表的许多评论。

以下代码更正了load()函数

中的这些问题

请注意对签名的更改以删除count参数

/*============================Load=*/
int load( struct item inven[] )
{
    FILE *fptr = fopen("inven.txt", "r");
    if( !fptr )
    {
        perror( "fopen to read 'inven.txt' failed" );
        return 0;
    }

    // implied else, fopen successful

    int count = 0;
    while( count < MAX && 2 == fscanf(fptr, "%d %19s", 
          &inven[ count ].itemID, 
           inven[ count ].itemname) )
    {
        count++;
    }

    fclose(fptr);

    return count;
} // end function: load

答案 2 :(得分:0)

@xing那是我在程序中改变的内容,现在它无法正常加载。

#include <stdio.h>
#include <stdlib.h>
#define MAX 12


//Structed Items

    struct item{//Opens Struct
    char itemname[20];
    char itemdes[30];
    int itemID;
    int itemOH;
    double itemUP;
    };//Closes Struct


// Function Declarations

    int getMenu_Choice ();
    int process (int choice, int count, struct item inven[]);
    int add (int count, struct item inven[]);
    int showall(int count, struct item inven[]);
    int find(int count, struct item inven[]);
    int modify(int count, struct item *inven);
    int save(int count, struct item inven[]);
    int load(int count, struct item inven[]);



int main (void)

{//OPENS MAIN

//Declarations

    int choice;
    struct item inven[MAX];
    int count = 0;

//Statements

    count = load (count, inven);

    do//opens
       {
        choice = getMenu_Choice ();
        count = process (choice, count, &inven[0]);
       }//closes

    while (choice != 0);

    save (count, inven);

    return 0;


} // CLOSE MAIN

/*============================getChoice=*/

int getMenu_Choice (void)

{//OPEN GETCHOICE

//Declarations
    int choice;

// Statements

    printf("\n\n**********************************");
    printf("\n              MENU             ");
    printf("\n\t1.Add New Item To Inventory       ");
    printf("\n\t2.View All Items In Inventory          ");
    printf("\n\t3.Find An Item           ");
    printf("\n\t4.Search And Modify An Item");
    printf("\n\t0.Exit                    ");
    printf("\n**********************************");
    printf("\nPlease Type Your Choice Using 0-4");
    printf("\nThen Hit Enter: ");
    scanf("%d", &choice);

    return choice;


}//CLOSES GET CHOICE


/*============================process=*/

int process (int choice, int count, struct item *inven)

{// OPEN PROCESS 

//Statements
    switch(choice)
        {
            case 1: count = add(count, inven);
                break;
            case 2: showall(count, inven);
                break;
            case 3: find(count, inven);
                break;
        case 4: modify(count, inven);
        break;
            case 0: exit;
                break;
            default: printf("Sorry Option Not Offered");
                break;

}//switch

return count;

}//CLOSE PROCESS


/*============================add one=*/
int add(int count, struct item *inven)

{//opens add one

// Declarations

    int i;


//Statements

    i = count;

    if (i < MAX) 
          {//opens if

              printf("\nEnter the Item ID: ");
              scanf("%d", &inven[i].itemID);

              printf("Enter the Item Name: ");
              scanf("%s", &inven[i].itemname);

              printf("Enter Item Description:\n");
              scanf("%s", &inven[i].itemdes);

          printf("Enter Number Of Items On Hand: ");
              scanf("%d", &inven[i].itemOH);

              printf("Enter The Unit Price Of The Item: ");
          scanf("%lf", &inven[i].itemUP);

    i++;

          }//closes if

     else {//opens else

              printf("\nSorry there seems to be no more room\n in your inventory. Please delete some current inventory.");

          };

    return i;


};//closes add one



/*============================showall=*/
int showall(int count, struct item *inven)

{//opens show all

//Declarations
    int i;

// Statements

    for(i = 0; i < count; i++)
       {//opens for

         printf("\nItem ID: %d", inven[i].itemID);
         printf("\nItem Name: %s", inven[i].itemname);
         printf("\nItem Description: %s", inven[i].itemdes);
         printf("\nItems On Hand: %d", inven[i].itemOH);
         printf("\nItem Unit Price: %0.2lf", inven[i].itemUP);

       };//closes for    

    return 0;

};//closes show all

/*============================find one=*/
int find(int count, struct item *inven)

{//opens find one

//Declarations 

    int i;
    int search;
    int found;

//Statements

    printf("Enter the Item ID to search\n");
    scanf("%d", &search);
    for (i = 0; i < count; i++)
        {//opens for

           if(inven[i].itemID == search)
             {//opens if

               printf("\nItem ID: %d", inven[i].itemID);
               printf("\nItem Name: %s", inven[i].itemname);
               printf("\nItem Description: %s", inven[i].itemdes);
               printf("\nItems On Hand: %d", inven[i].itemOH);
               printf("\nItem Unit Price: %0.2lf", inven[i].itemUP);
           found = 1;
               break;
             }//closes if

        }//closes for

if(i == count) 
  {//opens if

    printf("\nSorry That Item Isn't in OUR Inventory.");

  };//closes if

    return 0;

};//closes find one

/*============================modify=*/
int modify(int count, struct item *inven)

{//opens modify

//declarations

    int i;
    int search;
    int found;
    int choice;

    printf("Enter the Item ID to search\n");
    scanf("%d", &search);
    for (i = 0; i < count; i++)
        {//opens for

           if(inven[i].itemID == search)
             {//opens if

                printf("\nItem ID: %d", inven[i].itemID);
                printf("\nItem Name: %s", inven[i].itemname);
                printf("\nItem Description: %s", inven[i].itemdes);
                printf("\nItems On Hand: %d", inven[i].itemOH);
                printf("\nItem Unit Price: %0.2lf", inven[i].itemUP);
            found = 1;

      printf("\n\n        ****Modify Menu for %s*****", inven[i].itemname);
      printf("\n\n    Select a Number To Modify or 0 To Exit");
      printf("\n    =========================================");
      printf("\n    1. Item ID Number");
      printf("\n    2. Item Name");
      printf("\n    3. Item Description");
          printf("\n    4. Item Unit Price");
      printf("\n    5. Items On Hand"); 
      printf("\n                              Enter 0-5: ");
      scanf("%d", &choice); 


    switch(choice)
        {
            case 1: 
            printf("\nCurrent Item ID Number: %d", inven[i].itemID);
            printf("\nPlease Enter The New ID Number: ");
            scanf("%d", &inven[i].itemID);
            printf("\nNew Item ID: %d", inven[i].itemID);
                    break;

        case 2: 
            printf("\nCurrent Item Name: %s", inven[i].itemname);
            printf("\nPlease Enter The New Name: ");
            scanf("%s", &inven[i].itemname);
            printf("\nNew Item Name: %s", inven[i].itemname);
                    break;

            case 3:
                    printf("\nCurrent Item Description:\n%s", inven[i].itemdes);
            printf("\nPlease Enter The New Description:\n");
            scanf("%s", &inven[i].itemdes);
            printf("\nNew Item Description:\n%s", inven[i].itemname);
                    break;

            case 4:
                    printf("\nCurrent Item Unit Price: %0.2lf", inven[i].itemUP);
            printf("\nPlease Enter The New Unit Price: ");
            scanf("%lf", &inven[i].itemUP);
            printf("\nNew Item Unit Price: %0.2lf", inven[i].itemUP);
                    break;

            case 5:
                    printf("\nCurrent Items On Hand: %d", inven[i].itemOH);
            printf("\nPlease Enter The New On Hand Amount: ");
            scanf("%d", &inven[i].itemOH);
            printf("\nNew Amount Of Items On Hand: %d", inven[i].itemOH);
                    break;

            case 0: getMenu_Choice ();
                break;

            default: printf("Sorry Option Not Offered");
                break;

}//closes switch

       break;

}//closes if
}//closes for

    if(i == count)
       {//opens if

          printf("\nSorry Non existent");

       };//closes if

    return 0;

};//closes modify


/*============================Save=*/
int save(int count, struct item inven[])
{

//Declarations
    int i; 
    FILE *fptr; 


//Statements


fptr = fopen("inven.txt", "w");

for(i = 0; i < count; i++)
{
fprintf(fptr, "ID = %d\n", inven[i].itemID);
fprintf(fptr, "Name = %s\n", inven[i].itemname);
fprintf(fptr, "Des = %s\n", inven[i].itemdes);
fprintf(fptr, "On Hand = %d\n", inven[i].itemOH);
fprintf(fptr, "Unit Price = %lf\n", inven[i].itemUP);

};
fclose(fptr);

return 0;

};

/*============================Load=*/
int load(int count, struct item inven[])
{

    //Declarations 
    FILE *fptr;




   if ( ( fptr = fopen("inven.txt", "r")) == NULL) {
        fprintf ( stderr, "could not open inven.txt\n");
        return 0;
    }

    while ( ( fscanf(fptr, " ID = %d Name = %s Des = %s On Hand = %d Unit Price = %lf", &inven[count].itemID, inven[count].itemname, inven[count].itemdes, &inven[count].itemOH, &inven[count].itemUP)) == 2) 
{
        count++;
        if ( count >= MAX) {
            break;
        }
    }

    fclose(fptr);

    return count;
}