NotsoPr0
NotsoPr0

Reputation: 141

Crosses initialization of string and jump to label case

I am trying to do case menu for my program. And I always getting error of cross initialization, I have never before saw this error. Maybe someone could explain me what is happening wrong with my code.

#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <fstream>

using namespace std;

#define N_CARS 1

struct car{
    string model;
    int year;
    double price;
    bool available;
}cars [N_CARS];


void menu();
void mainMenu();

void writeToFile(ofstream &outputFile , const car& p)
{
    outputFile << p.model << " "
               << p.year << " "
               << p.price << " "
               << p.available<<"\n";
}

int choice1 = 0;


int main(int argc, char** argv) {

    menu();
    return 0;
}


void menu() {

    do {
        mainMenu();

        switch(choice1) {

            case 1:
                string mystr;
                string mystr2;
                string mystr3;

                int n;
                for (n=0; n<N_CARS; n++)
                {
                    cout << "Enter title: ";
                    getline (cin,cars[n].model);
                    cout << "Enter year: ";
                    getline (cin,mystr);
                    stringstream(mystr) >> cars[n].year;
                    cout << "Enter price: ";
                    getline (cin,mystr2);
                    stringstream(mystr2) >> cars[n].price;
                    cout << "Choose availability: ";
                    getline (cin,mystr3);
                    stringstream(mystr3) >> cars[n].available;
                }

                ofstream outputFile;
                outputFile.open("bla.txt", fstream::app);
                for (n=0; n<N_CARS; n++)
                    writeToFile(outputFile, cars[n]);
                outputFile.close();
                break;

            case 2:
                break;

            case 5:
                break;
        }

    } while(choice1 != 5);

}


void mainMenu(void) {

    cout << "Main Menu\n";
    cout << "1 - Enter Car\n";
    cout << "5 - Quit\n";
    cout << "Please choose: ";

    cin >> choice1;
}

Errors:

In function 'void menu()':
    [Error] jump to case label [-fpermissive]
    [Error] crosses initialization of 'std::ofstream outputFile'
    [Error] crosses initialization of 'std::string mystr3'
    [Error] crosses initialization of 'std::string mystr2'
    [Error] crosses initialization of 'std::string mystr'

Upvotes: 3

Views: 11729

Answers (2)

Christian Hackl
Christian Hackl

Reputation: 27538

case labels are really a lot like dreaded goto labels; they do not constitute a new scope. Consequently, a switch selecting the correct case label to jump to is, for better or worse, a lot like goto statement jumping to a label. The jump is not allowed to cross the initialisation of your various objects - exactly as the error messages say.

The cleanest thing for you to do would be to cut everything between case 1: and break; case 2: and paste it into a new function called something like enterCar.

void enterCar() {
    // code previously found between the case labels
}

// ...
switch(choice1) {
    case 1: enterCar(); break;
    case 2:
    // ...
}

A function constitutes a new scope in which your local objects can be correctly initialised. As a bonus, you are making first steps towards leaving all the spaghetti code behind you.

Upvotes: 5

The Techel
The Techel

Reputation: 873

You have to enclose variable definitions within case-blocks with scope brackets {}.

Another thing: forget about #define for comple time constants, use constexpr:

constexpr size_t NumCars = 5;

Also note the size_t: for variables and constants describing sizes, e.g. array sizes or indices, use size_t.

Further, you include cstdlib and stdlib.h. Headerfiles from the C-standardlibrary should always be included with the c-prefix and .h-omission, so kick out the stdlib.h. You don't need it anyway.

Upvotes: 1

Related Questions