1

The 1. and 3. menu items are working, but if I choose the 2. menu item it's not listing my data. Why is that? (It has to be compiled and run in linux command line [NO IDE!])

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>

struct log{
    int     id;
    char    name[20];
    char    location[20];
    int     quantity;
    char    quantity_type[10];
    time_t  added;
};

char fname[] = "data2.dat";

void add();
void listAll();

int nextId();

int main(){
    int ch;

    while(1){
        system("clear");

        printf("///Log stuff!///\n\n");

        printf("1. Add\n");
        printf("2. List all\n");            
        printf("0. Exit\n");

        printf("\n///////////////////////////////\n\n");

        printf("Choose a number from the menu: ");
        scanf("%d", &ch);

        switch(ch){
            case 1: add();
            break;

            case 2: listAll();
            break;

            case 0: exit(0);
            break;
        }    
    }   

    return 0;
}

void add(){
    FILE *f;
    struct log log;

    f = fopen(fname, "ab");
    if(f == NULL){perror("Can't open!\n");}

    log.id = nextId();
    printf("\nName: ");
    scanf("%s", log.name);
    printf("\nLocation: ");
    scanf("%s", log.location);
    printf("\nQuantity: ");
    scanf("%d", &log.quantity);
    printf("\nQuantity type: ");
    scanf("%s", log.quantity_type);
    log.added = time(NULL);

    fwrite(&log,sizeof(log),1,f);

    fclose(f);
}

void listAll(){
    FILE *f;
    struct log log;

    f = fopen(fname,"rb");
    if(f == NULL){perror("Can't open!\n");exit(1);}

    printf("\n///////////////////////////////\n\n");        
    printf("\tList of all data\n\n");
    printf("///////////////////////////////\n\n");

    while(fread(&log,sizeof(log),1,f) == 1){        
        printf("%d\t",log.id);
        printf("%s\t",log.name);
        printf("%s\t",log.location);
        printf("%d\t",log.quantity);
        printf("%s\t",log.quantity_type);
        printf("%s",ctime(&log.added));
    }
    printf("\n///////////////////////////////\n\n");

    fclose(f);
}

int nextId(){
    FILE *f;
    struct log log;
    int id = 1;

    f = fopen(fname, "rb"); 
    if(f == NULL){perror("Can't open!\n");}

    while(!feof(f)){
        fread(&log, sizeof(log), 1, f);
        if(log.id >= id){id = log.id + 1;}
    }

    fclose(f);

    return id;
}
  • Is there a more elegant way to do this task?
smolik
  • 11
  • 2

1 Answers1

0

This menu display/input choice/switch section of the code has a logic error the screen is being cleared before the user has a chance to look at any displayed data.

Proper placement of calls to system(clear) and getchar() will fix the problem a function should only have 1 normal exit. Any other exit points should be only for error conditions

You might try the following:

 system(clear);

 int done = 0;
 while( !done )
 {
     printf("///Log stuff!///\n\n");

     printf("1. Add\n");
     printf("2. List all\n");
     printf("3. Exit\n");

     printf("\n///////////////////////////////\n\n");

     printf("Choose a number from the menu: ");
     if( 1 != scanf("%d", &ch) )
     { // then scanf failed
         perror( "scanf for menu choice failed" );
         exit( EXIT_FAILURE );
     }

     // implied else, scanf successful

     // eliminate menu from screen
     system(clear);

     switch(ch)
     {
        case 1:
            add();
        break;

        case 2:
            listAll();
            printf( "\npress any key to continue\n" );
            getchar();
        break;

        case 3:
            done=1;
        break;

        default:
            printf("\nyou entered an invalid menu selection, try again\n");
            break;
     } // end switch
}   // end while
Taylor Price
  • 622
  • 1
  • 8
  • 21
user3629249
  • 16,402
  • 1
  • 16
  • 17
  • I changed the '0' menu selection to '3' because if the user entered (for instance) 'a', then 'ch' would be unchanged. The scanf failure would exit the program. so you should change the scanf to get a string, then use something like 'atoi()' to get a number from that string. (which might result in 0 when the user input was not numeric) but, at least the program would not exit when the user entered invalid characters – user3629249 Mar 27 '15 at 18:35