-1

I want to call the function nameOnFile(); to enter a name of a file. The returned string is sent to read(); to load the file and check it. If the file does not exist, I want to give the user the opportunity to start again.

First attempt works. But the second error, the program jumps back to main.

*This is what happends....

Whats is the name of the file? wrongFile

The file coulde note be opend

Do you want to try again? j/n j

Whats is the name of the file? wrongFileAgain

Do you want to try again? j/n j

Do you want to test the program again? j/n

*End

The last string is from main. Should not the program go back to the nameOneFile() function?

How can I solve the problem?

int main(){

    string receivedFilename, receivedString;
    char x;

    do{
    receivedFilename = nameOnFile();
    receivedString = read(receivedFilename);

        cout << "\nDo you want to test the program again? j/n " << endl;
        cin >> x;
        cin.ignore(10000,'\n');


    }while(x == 'j' || x == 'J');
}


string nameOnFile(){

    string nameOnFileTxt;

    cout << "What is the name of the file?";
    getline(cin, nameOnFileTxt);

    if(nameOnFileTxt.rfind(".txt") > nameOnFileTxt.length()){

        nameOnFileTxt.append(".txt");

    }

   return nameOnFileTxt;
   }


string read(string theFileNamn){

    ifstream fin(theFileNamn.c_str());
    string fileAsString, words;
    char x;

    if ( !fin ){

      cout << "The file could not be opened" << endl;
      cout << "Do you want to try again? j/n" << endl;

      cin >> x;
      cin.ignore(10000,'\n');

      if(x == 'j' || x == 'J'){

          nameOnFile();
      }
      else{

          exit( EXIT_FAILURE );
      }

    }
    else{

       while(getline(fin, words)){

          fileAsString.append(words);

    }

    return fileAsString;
    }
}
GorAhl
  • 61
  • 7

3 Answers3

1
// this does not change again, it compares it against true, return value is unused
again == true;

is not an assignment, this is:

again = true;

Much simpler is to do:

do { ... } while(x == 'j' || x == 'J');

don't you think?

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
  • Better still to write a bool prompt(const char* txt) { } which does the output, reading the input, and testing for Ja or Nein. ... and then put *that* in the termination condition of the do while loop. – Martin Bonner supports Monica Dec 12 '15 at 14:49
0

Your call to nameOnFile in read doesn't do what you want. You will read a filename, but then just ignore it. If you want to do that, you will need to declare fin (but not open it), then loop until either you open the file successfully, or the user doesn't want to try again.

0

To have a non-local control flow jump from some inner function back to main you probably want some exception handling.

Read more about C++ exceptions (and their relation with destructors, notably RAII), throw expressions, try-catch blocks. You might consider some throw std::runtime_error("message"); in the inner function, and using try { ...} catch(std::runtime_error err) {...} in your main (or you could consider having your own exception class, inheriting from std::runtime_error ...)

Read a good book on Programming using C++

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547