1

I've been having difficulties in searching a text in a text file when I choose case 4 or 'show video details'. It seems that ifstream in a switch statement is not working. This is my code:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;
int main()
{
    int choice;
    //4
    string line;
    bool iffound = false;
    string id1;
    ifstream file("test.txt");

menu:
    cout << "MENU" << endl
         << endl;
    cout << "[1] NEW VIDEO" << endl;
    cout << "[2] RENT A VIDEO" << endl;
    cout << "[3] RETURN A VIDEO" << endl;
    cout << "[4] SHOW VIDEO DETAILS" << endl;
    cout << "[5] DISPLAY ALL VIDEOS" << endl;
    cout << "[6] CHECK VIDEO AVAILABILITY" << endl;
    cout << "[7] CUSTOMER'S MAINTENANCE" << endl;
    cout << "[8] EXIT PROGRAM" << endl;
    cout << "Choice: ";

    cin >> choice;

    switch (choice)
    {
    case 1:
        break;
    case 2:
        break;
    case 3:
        break;
    case 4:
    {
        file.open("test.txt");
        cout << "<< SHOW VIDEO DETAILS >>" << endl
             << endl;
        cout << "Enter Movie ID: ";
        cin >> id1;
        string idnum1 = "VIDEO ID: " + id1;
        cout << idnum1 << endl;

        while (file.good())
        {
            getline(file, line);
            if (line == idnum1)
            {
                iffound = true;
                for (int i = 0; i <= 3; i++)
                {
                    getline(file, line);
                    cout << line << endl;
                }
                break;
            }
        }
        file.close();

        if (iffound != true)
        {
            cout << "Video not found!" << endl;
        }
    }
    break;
    case 5:

        break;
    case 6:
        break;
    case 7:
        break;
    case 8:
        break;
    }
}

And this is my text file:

VIDEO ID : 1
MOVIE TITLE     : IT
GENRE           : HORROR
PRODUCTION      : NEW LINE CINEMA
NUMBER OF COPIES: 0
it.jpg
VIDEO ID : 2
MOVIE TITLE     : THE CALL
GENRE           : HORROR
PRODUCTION      : YONG FILM
NUMBER OF COPIES: 3
thecall.jpg
VIDEO ID : 3
MOVIE TITLE     : I AM LEGEND
GENRE           : HORROR
PRODUCTION      : VILLAGE ROADSHOW
NUMBER OF COPIES: 6
iamlegend.jpg

When I input a valid Id, for instance, 1, it outputs 'video not found', when clearly the Id is present.

But when I try this code, where there is no switch statement, it works:

int main()
{
    ifstream file("test.txt");
    string line;
    bool find = false;
    string id;
    string img;

    cout << "Enter movie ID: ";
    cin >> id;
    string idnum = "VIDEO ID : " + id;
    cout << idnum << endl;

    while (file.good())
    {
        getline(file, line);
        if (line == idnum)
        {
            find = true;
            for (int i = 0; i < 4; i++)
            {
                getline(file, line);
                cout << line << endl;
            }
            getline(file, img);
            cout << img;
        }
    }
    file.close();

    if (find != true)
    {
        cout << "Movie Not Found" << endl;
    }
    return 0;
}

But I need to run it in a switch statement.

anastaciu
  • 20,013
  • 7
  • 23
  • 43
Noran
  • 13
  • 4
  • 1
    `string idnum1 = "VIDEO ID: " + id1;` vs `string idnum = "VIDEO ID : " + id;` – Mike Vine Apr 06 '21 at 09:20
  • 1
    Possibly related: [Why does std::getline() skip input after a formatted extraction?](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – Yksisarvinen Apr 06 '21 at 09:24
  • @MikeVine oh i didn't notice that but unfortunately, it still didn't work – Noran Apr 06 '21 at 09:27
  • If the second works why don't you use it instead, i.e. copy the parsing code to your case 4? – anastaciu Apr 06 '21 at 09:38
  • You need only one call to `std::cout` to display the **entire** menu. What happens if the user types `"one"` for the choice (or slips and taps `'e'` or `'r'` reaching for `'4'`)? – David C. Rankin Apr 06 '21 at 09:40
  • Probably relevant: https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons/13536879?r=SearchResults&s=9|28.1373#13536879 – Ulrich Eckhardt Apr 06 '21 at 09:48
  • 1
    As a new user here, please take the [tour] and read [ask]. In particular, you should have extracted a [mcve] from your code, which might have given you the hint required to solve the issue yourself, in particular that the problem may have nothing to do with switch statements. – Ulrich Eckhardt Apr 06 '21 at 09:50
  • @Noran in the non working code snippet, you are reopening an already opened file, that's the problem (aside from the missing space), see my answer for more detail. – anastaciu Apr 06 '21 at 10:35

2 Answers2

1

It's not related to the switch, the problem (aside from the already identified missing space in the concatenated string) is that you are reopening the already opened file a second time (notice that you don't do that in the working code snippet).

What happens is that the error state of the stream buffer will be set to failbit and good() will be returning false, everything inside the while loop will not be executed.

Open it only once and your code will work fine.

Instead of:

ifstream file("test.txt");

Use:

ifstream file;

Or just remove:

file.open("test.txt");

And of course add the space to the concatenated string:

string idnum1 = "VIDEO ID : " + id1;
                         ^

Live demo


I should point out that you should revisit your usage of using namespace std; check this post for reasons and alternatives:

Why is "using namespace std;" considered bad practice?

anastaciu
  • 20,013
  • 7
  • 23
  • 43
-1

Change

string idnum1 = "VIDEO ID: " + id1;

to

string idnum1 = "VIDEO ID : " + id1;

Adds one space.

Evgeny
  • 721
  • 3
  • 5