-2

I have developed a little program which reads in data from a file, does some specific computation and prints the results to the screen and another file. This program works fine whilst doing this but when I try to add a user menu using 'switch' I run into problems. The code with the user menu compiles OK but when I run it, it crashes or doesn't work correctly, depending which option you take. So my question is: can you please help identify where I have gone wrong? I am relatively new at this and don't know a lot about the 'switch' command.

I know I should use functions, that's next! I'll include both sets of code:

Program 1 - Without Menu

#include <stdlib.h>
#include <stdio.h>

// define structure
typedef struct car
 {
    char brand[20];
    char model[20];
    int engine;
    float price;
    int year;
 } car_type;

int main(void)
{

 car_type car[20];
 int year, i;
 char brand[20], model[20], space;
 int engine;
 float price, new_price;
 i = 0;

 // read from file
 FILE* fp;
 fp = fopen("indata.txt", "r");
 FILE* fp_out;
 fp_out = fopen("outdata.txt", "w");
 if (fp == NULL)
    {
        printf("Opening of file failed\n");
        return 0;
    }
 else
    {
        printf("Brand \t Model \t Engine \t Price \t Old(0)/New(1) \t New Price\n\n");
        fprintf(fp_out, "Brand \t Model \t Engine \t Price \t Old(0)/New(1) \t New Price\n");

        while (!feof(fp))
            {
                fscanf(fp, "%s%c%s%c%d%c%f%c%d\n", &car[i].brand, &space, &car[i].model, &space, &car[i].engine, &space, &car[i].price, &space, &car[i].year);
                //display info
                printf("%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
                fprintf(fp_out, "%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
                // Compute new price
                    if (car[i].year > 0)
                        {
                            printf("N/A\n");
                            fprintf(fp_out, "N/A\n");
                        }

                    else
                        {
                            if (car[i].engine >= 1600 && car[i].price>= 20000)
                                {
                                    new_price = (car[i].price)*(0.85);
                                    printf(" %1.1f euro \n", new_price);
                                    fprintf(fp_out," %1.1f euro \n", new_price);
                                }
                            else
                                {
                                    if (car[i].engine>=1600)
                                        {
                                            new_price = (car[i].price)*(0.95);
                                            printf(" %1.1f euro \n", new_price);
                                            fprintf(fp_out," %1.1f euro \n", new_price);
                                        }
                                    else
                                        {
                                            if (car[i].price >= 20000)
                                                {
                                                    new_price = (car[i].price)*(0.9);
                                                    printf(" %1.1f euro \n", new_price);
                                                    fprintf(fp_out," %1.1f euro\n", new_price);
                                                }
                                            else
                                                {
                                                    printf("N/A \n");
                                                    fprintf(fp_out, "N/A\n");
                                                }
                                        }
                                }
                        }
            i++;
            }
    }
 return(EXIT_SUCCESS);
}

Program 2 - With Menu

#include <stdlib.h>
#include <stdio.h>

// define structure
typedef struct car
 {
    char brand[20];
    char model[20];
    int engine;
    float price;
    int year;
 } car_type;

int main(void)
{

 car_type car[20];
 int year, i, option;
 char brand[20], model[20], space;
 int engine;
 float price, new_price;
 i = 0;

 // read from file
 FILE* fp;
 fp = fopen("indata.txt", "r");
 FILE* fp_out;
 fp_out = fopen("outdata.txt", "w");

 //user menu
 option = 0;
 while (option != 4)
 {
     printf("To have output printed on to screen only - select option 1 \n");
     printf("To have output printed to file only - select option 2 \n");
     printf("to have output printed to both - select option 3 \n");
     printf("To exit - press 4 \ncc32");
     scanf("%d", &option);
     switch (option)
        {
            //Case 1
            case 1:
            {
                if (fp == NULL)
                    {
                        printf("Opening of file failed\n");
                        return 0;
                    }

                else
                    {
                        printf("Brand \t Model \t Engine \t Price \t Old(0)/New(1) \t New Price\n\n");
                        while (!feof(fp))
                            {
                                //display info
                                printf("%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);

                                // Compute new price
                                if (car[i].year > 0)
                                    {
                                        printf("N/A\n");
                                    }
                                else
                                    {
                                        if (car[i].engine >= 1600 && car[i].price>= 20000)
                                            {
                                                new_price = (car[i].price)*(0.85);
                                                printf(" %1.1f euro \n", new_price);
                                            }
                                        else
                                            {
                                                if (car[i].engine>=1600)
                                                    {
                                                        new_price = (car[i].price)*(0.95);
                                                        printf(" %1.1f euro \n", new_price);
                                                    }
                                                else
                                                    {
                                                        if (car[i].price >= 20000)
                                                            {
                                                                new_price = (car[i].price)*(0.9);
                                                                printf(" %1.1f euro \n", new_price);
                                                            }
                                                        else
                                                            {
                                                                    printf("N/A \n");
                                                            }
                                                    }
                                            }
                                    }
                            i++;
                            }
                    }
            break;
            }

            //Case 2
            case 2:
                {
                    if (fp == NULL)
                        {
                            printf("Opening of file failed\n");
                            return 0;
                        }
                    else
                        {
                            fprintf(fp_out, "Brand \t Model \t Engine \t Price \t Old(0)/New(1) \t New Price\n");

                            while (!feof(fp))
                                {
                                    fscanf(fp, "%s%c%s%c%d%c%f%c%d\n", &car[i].brand, &space, &car[i].model, &space, &car[i].engine, &space, &car[i].price, &space, &car[i].year);
                                    //display info
                                    fprintf(fp_out, "%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
                                    // Compute new price
                                    if (car[i].year > 0)
                                        {
                                            fprintf(fp_out, "N/A\n");
                                        }

                                    else
                                        {
                                            if (car[i].engine >= 1600 && car[i].price>= 20000)
                                                {
                                                    new_price = (car[i].price)*(0.85);
                                                    fprintf(fp_out," %1.1f euro \n", new_price);
                                                }
                                            else
                                                {
                                                    if (car[i].engine>=1600)
                                                        {
                                                            new_price = (car[i].price)*(0.95);
                                                            fprintf(fp_out," %1.1f euro \n", new_price);
                                                        }
                                                    else
                                                        {
                                                            if (car[i].price >= 20000)
                                                                {
                                                                    new_price = (car[i].price)*(0.9);
                                                                    fprintf(fp_out," %1.1f euro\n", new_price);
                                                                }
                                                            else
                                                                {
                                                                    fprintf(fp_out, "N/A\n");
                                                                }
                                                        }
                                                }
                                        }
                                i++;
                                }
                        }
                    break;
                }

            //Case 3
            case 3:
            {
                if (fp == NULL)
                    {
                        printf("Opening of file failed\n");
                        return 0;
                    }
                else
                    {
                        printf("Brand \t Model \t Engine \t Price \t Old(0)/New(1) \t New Price\n\n");
                        fprintf(fp_out, "Brand \t Model \t Engine \t Price \t Old(0)/New(1) \t New Price\n");

                        while (!feof(fp))
                            {
                                fscanf(fp, "%s%c%s%c%d%c%f%c%d\n", &car[i].brand, &space, &car[i].model, &space, &car[i].engine, &space, &car[i].price, &space, &car[i].year);
                                //display info
                                printf("%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
                                fprintf(fp_out, "%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
                                // Compute new price
                                    if (car[i].year > 0)
                                        {
                                            printf("N/A\n");
                                            fprintf(fp_out, "N/A\n");
                                        }

                                    else
                                        {
                                            if (car[i].engine >= 1600 && car[i].price>= 20000)
                                                {
                                                    new_price = (car[i].price)*(0.85);
                                                    printf(" %1.1f euro \n", new_price);
                                                    fprintf(fp_out," %1.1f euro \n", new_price);
                                                }
                                            else
                                                {
                                                    if (car[i].engine>=1600)
                                                        {
                                                            new_price = (car[i].price)*(0.95);
                                                            printf(" %1.1f euro \n", new_price);
                                                            fprintf(fp_out," %1.1f euro \n", new_price);
                                                        }
                                                    else
                                                        {
                                                            if (car[i].price >= 20000)
                                                                {
                                                                    new_price = (car[i].price)*(0.9);
                                                                    printf(" %1.1f euro \n", new_price);
                                                                    fprintf(fp_out," %1.1f euro\n", new_price);
                                                                }
                                                            else
                                                                {
                                                                    printf("N/A \n");
                                                                    fprintf(fp_out, "N/A\n");
                                                                }
                                                        }
                                                }
                                        }
                            i++;
                            }
                    }
            break;
            }
        }

 }
 return(EXIT_SUCCESS);
}
Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
  • Aside: hint about `while (!feof(fp))` http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong `feof()` only becomes true *after reading beyond the end of a file* - not **when** you have reached its end. You do better checking the result of the file read functions - the numbers of fields read by `fscanf()` or the success of `fgets()`. – Weather Vane May 12 '15 at 17:06
  • The `break` in `case 2:` is not the last instruction in that code block. – Weather Vane May 12 '15 at 17:14
  • Yes sorry again for the format of this program @iharob , I know it looks very awkward. As I mentioned, learning how to effectively use functions is next on my list, to help prevent it looking so messy. However I know that the majority of the code works well enough to suit my purposes, it's just the menu that I'm struggling with. Thanks – YellowKing May 12 '15 at 17:31

1 Answers1

0

It could be done more simply than with a switch statement and all the repetitions. If you weed out the exit (and invalid) options first, you are left with executing one or both of the option perms:

if (option & 1)         // to terminal
    printf("%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
if (option & 2) {       // to file
    if ((fp_out = fopen("outdata.txt", "w")) == NULL)
        exit(1);        // improve this
    fprintf(fp_out, "%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
    fclose(fp_out);
}

You could reduce the repetition even more by preparing the (identical) output first.

char data_str[500];
sprintf(data_str, "%7s\t %6s\t %4d cc\t %1.1f euro\t %d\t ", car[i].brand, car[i].model, car[i].engine, car[i].price, car[i].year);
if (option & 1)         // to terminal
    printf("%s\n", data_str);
if (option & 2) {       // to file
    if ((fp_out = fopen("outdata.txt", "w")) == NULL)
        exit(1);        // improve this
    fprintf(fp_out, "%s\n", data_str);
    fclose(fp_out);
}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56