Thread: Print from File Won't Return to Program After completion.

  1. #1
    Registered User
    Join Date
    Feb 2018
    Posts
    6

    Print from File Won't Return to Program After completion.

    I've been working on creating a program for school. The project was turned in yesterday, but I never could find a solution to my problem so I'm asking now after the project was turned in.

    The game is Left-Center-Right and all my code works, but printing the rules hangs after finishing and won't return to the program to continue. I tried declaring as different functions, tried numerous versions of return and exit, but it still happens. What am I doing wrong?

    Code:
    void printRules();
    Code:
    // show players the rules
        printRules();
    Code:
    void printRules() {
    
    
        for (size_t i = 0; i <= 1; i++)
        {
            ifstream rulesOfTheGame; // create a file stream
            char ruleLine[255]; // declare output character string
    
    
            rulesOfTheGame.open("lcr-rules-to-print.txt"); // open game rules file
                                                           // code to check for existence of file adapted from 
                                                           // https://www.uow.edu.au/~lukes/TEXTBOOK/notes-cpp/io/readtextfile.html
            if (!rulesOfTheGame) {
                cerr << "Unable to open the rules file";
                exit(1);   // call system to stop
            }
            // reads the file in sequence to the end
            while (!rulesOfTheGame.eof())
            {
                rulesOfTheGame.getline(ruleLine, 255); // get line and place in string
                if (rulesOfTheGame) cout << ruleLine << endl; // prints string to console
    
    
            }
                rulesOfTheGame.clear();
                rulesOfTheGame.close();
                }
            }

  2. #2
    Guest
    Guest
    I don't see anything inherently wrong with your code. If you just write a program that calls the function you specified:
    Code:
    int main()
    {
        printRules();
    }
    Does that hang?

    If not, your problem might lie elsewhere. Post more of the surrounding code if you can't figure it out.

  3. #3
    Registered User
    Join Date
    Feb 2018
    Posts
    6
    Quote Originally Posted by Guest View Post
    Does that hang?

    If not, your problem might lie elsewhere. Post more of the surrounding code if you can't figure it out.
    It must be somewhere else. I created and compiled that in a separate location and it does the same thing.

    I did notice one thing.

    The command prompt is accepting inputs while it's hung. I hadn't noticed it before. While it ran I entered 1,2,3,4,5 just because and when I escaped the program the cmd had the following input:

    Code:
    C:\Source\Repos>1
    '1' is not recognized as an internal or external command,
    operable program or batch file.
    
    
    C:\Source\Repos>2
    '2' is not recognized as an internal or external command,
    operable program or batch file.
    
    
    C:\Source\Repos>3
    '3' is not recognized as an internal or external command,
    operable program or batch file.
    
    
    C:\Source\Repos>4
    '4' is not recognized as an internal or external command,
    operable program or batch file.
    
    
    C:\Source\Repos>5
    '5' is not recognized as an internal or external command,
    operable program or batch file.
    In case it's relevant, I'm using Visual Studio Community 2017 on Windows 10. I haven't tried this in Debian to see if it gives the same issue.

    Also, these are my includes and I'm using namespace std
    Code:
    #include <iostream>
    #include <string>
    #include <stdio.h>     // needed for reading from rules file
    #include <cstdlib>     // needed for using random number generator
    #include <ctime>       // needed to initilize random number generator 
    #include <fstream> // call the file management class

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    It seems to me that your IDE is holding the console window open after the program has exited. This is a convenience feature in place of press any key traps at the end of programs.

    You can turn this off.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Feb 2018
    Posts
    6
    I actually just tried it in Linux with g++ and editing with kate. It does the exact same thing.

    I have no idea.

  6. #6
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    You need to post the entire program so we can run it ourselves.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  7. #7
    Registered User
    Join Date
    Feb 2018
    Posts
    6
    Quote Originally Posted by john.c View Post
    You need to post the entire program so we can run it ourselves.
    No problem.

    main.cpp
    Code:
    #include <iostream>
    #include <string>
    #include <stdio.h> // needed for reading from rules file
    #include <cstdlib> // needed for using random number generator
    #include <ctime> // needed to initilize random number generator 
    #include <fstream> // call the file management class
    
    
    using namespace std;
    
    
    void printRules();
    
    
    int main(int argc, const char * argv[])
    {
    
    
        // wide scoped variables
        string waiting; // delete after completing game code creation
        bool winner = false;
        std::string winnerName = "";
    
    
        // set number of chips in pot
        int potChips = 0;
    
    
        // initialize dice roll generator 
        srand((unsigned)time(NULL));
    
    
        // create player instances
        Player p1(1, "", 3, false); // assigned player number, chip count, and winner status for player 1
        Player p2(2, "", 3, false); // assigned player number, chip count, and winner status for player 2
        Player p3(3, "", 3, false); // assigned player number, chip count, and winner status for player 3
    
    
    // show players the rules
        printRules();
    
    
        // Get the names of the players and assign to playerName array
        string playerNames[4];
    
    
        for (int i = 1; i <= 3; i++)
        {
            cout << "What is player " << (i) << "'s name?" << endl;
            std::cin >> playerNames[i];
        }
    
    
        // adding player names to player class instances
        p1.pName = playerNames[0];
        p2.pName = playerNames[1];
        p3.pName = playerNames[2];
    
    
        // Determines if there is a winner based on chip count
        while (winner == false) {
    
    
    
    
            for (int currentPlayer = 1; currentPlayer <= 3; currentPlayer++) {
                cout << endl;
                cout << "Current player is " << playerNames[currentPlayer] << endl << endl;
    
    
                // derive dice values for each chip player has.
                for (int RolledTheDice = 1; RolledTheDice <= 3; RolledTheDice++)
                {
                    // create random number to represent rolled dice
                    int diceValue = (rand() % 6) + 1;
    
    
                    // chip assignment based on value in diceValues array
                    switch (diceValue) {
                    case 1: // move chips left
                        cout << "The roll was an 'L', moved one chip to the left " << endl;
                        // assign player chips to player on the left
                        if (currentPlayer == 1 and p1.pChips > 0) // case where current player is p1
                        {
                            // check if player is out of chips and skip turn
                            if (p1.pChips == 0) {
                                cout << p1.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            p3.pChips = p3.pChips + 1; // moves chips to player three
                            p1.pChips = p1.pChips - 1; // removes the chips from player one
                            break;
                        }
                        else if (currentPlayer == 2 and p2.pChips > 0)    // case where current player is p2
                        {
                            // check if player is out of chips and skip turn
                            if (p2.pChips == 0) {
                                cout << p2.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            p1.pChips = p1.pChips + 1;
                            p2.pChips = p2.pChips - 1; // removes the chips from player two
                            break;
                        }
                        else if (currentPlayer == 3 and p3.pChips > 0) { // case where current player is p3
                            // check if player is out of chips and skip turn
                            if (p3.pChips == 0) {
                                cout << p3.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            p2.pChips = p2.pChips + 1;
                            p3.pChips = p3.pChips - 1; // removes the chips from player three
                            break;
                        }
                        else
                        {
                            break;
                        }
                    case 2: // move chips pot
                        cout << "The roll was a 'C', moved one chip to the pot " << endl;
                        if (currentPlayer == 1 and p1.pChips > 0) // case where current player is p1
                        {
                            // check if player is out of chips and skip turn
                            if (p1.pChips == 0) {
                                cout << p1.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            potChips = potChips + 1; // moves chips to player two
                            p1.pChips = p1.pChips - 1; // removes the chips from player one
                            break;
                        }
                        else if (currentPlayer == 2 and p2.pChips > 0) // case where current player is p2
                        {
                            // check if player is out of chips and skip turn
                            if (p2.pChips == 0) {
                                cout << p2.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            potChips = potChips + 1; // moves chips to player three
                            p2.pChips = p2.pChips - 1; // removes the chips from player two
                            break;
                        }
                        else if (currentPlayer == 3 and p3.pChips > 0) { // case where current player is p3
                            // check if player is out of chips and skip turn
                            if (p3.pChips == 0) {
                                cout << p3.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            potChips = potChips + 1; // moves chips to player 1
                            p3.pChips = p3.pChips - 1; // removes the chips from player three
                            break;
                        }
                        else {
                            break;
                        }
                    case 3: // move chips to right
                        cout << "The roll was an 'R', moved one chip to the right " << endl;
                        // assign player chips to player on the right
                        if (currentPlayer == 1 and p1.pChips > 0) // case where current player is p1
                        {
                            // check if player is out of chips and skip turn
                            if (p1.pChips == 0) {
                                cout << p1.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            p2.pChips = p2.pChips + 1; // moves chips to player two
                            p1.pChips = p1.pChips - 1; // removes the chips from player one
                            break;
                        }
                        else if (currentPlayer == 2 and p2.pChips > 0) // case where current player is p2
                        {
                            // check if player is out of chips and skip turn
                            if (p2.pChips == 0) {
                                cout << p2.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            p3.pChips = p3.pChips + 1; // moves chips to player three
                            p2.pChips = p2.pChips - 1; // removes the chips from player two
                            break;
                        }
                        else if (currentPlayer == 3 and p3.pChips > 0) { // case where current player is p3
                            // check if player is out of chips and skip turn
                            if (p2.pChips == 0) {
                                cout << p3.pName << " your turn has been skipped because you have no chips" << endl;
                                break;
                            }
                            p1.pChips = p1.pChips + 1; // moves chips to player 1
                            p3.pChips = p3.pChips - 1; // removes the chips from player three
                            break;
                        }
                    default:
                        cout << "The Roll was a '*'. No chips were moved" << endl;
                    }
                    // continually check patter for winner
                };
                if (p1.pChips == 0 and p2.pChips == 0)
                {
                    winnerName = p3.pName;
                    cout << endl << winnerName << " wins" << endl;
                    p3.pWinner = true;
                    winner = true;
    
    
                }
                else if (p2.pChips == 0 and p3.pChips == 0) {
    
    
                    winnerName = p1.pName;
                    cout << endl << winnerName << " wins" << endl;
                    p1.pWinner = true;
                    winner = true;
    
    
                }
                else if (p1.pChips == 0 and p3.pChips == 0) {
                    winnerName = p2.pName;
                    cout << endl << winnerName << " wins" << endl;
                    p2.pWinner = true;
                    winner = true;
                }
                else {
                    system("pause");
    
    
                }
            };
            cout << endl;
            cout << endl;
            cout << "Player one has " << p1.pChips << endl;
            cout << "Player two has " << p2.pChips << endl;
            cout << "Player three has " << p3.pChips << endl;
            cout << "Chips in the pot are " << potChips << endl;
    
    
        }
    
    
    
    
    }
    
    
    void printRules() {
    
    
        for (size_t i = 0; i <= 1; i++)
        {
            ifstream rulesOfTheGame; // create a file stream
            char ruleLine[255]; // declare output character string
    
    
            rulesOfTheGame.open("lcr-rules-to-print.txt"); // open game rules file
    
    
                                                         // code to check for existence of file adapted from 
                                                         // C++ Notes: Reading Text Files
            if (!rulesOfTheGame) {
                cerr << "Unable to open the rules file";
                exit(1); // call system to stop
            }
            // reads the file in sequence to the end
            while (!rulesOfTheGame.eof())
            {
                rulesOfTheGame.getline(ruleLine, 255); // get line and place in string
                if (rulesOfTheGame) cout << ruleLine << endl; // prints string to console
    
    
            }
    
    
    
    
                rulesOfTheGame.clear();
                rulesOfTheGame.close();
                }
            }
    player.h
    Code:
    #pragma once#include <string>
    
    
    class Player
    {
    
    
    private:
        int Number;
        std::string name;
        int chips;
        bool Winner;
    
    
    
    
    public:
        int pNumber = Number;
        std::string pName = name;
        int pChips = chips;
        bool pWinner = Winner;
    
    
        Player(int pNumber,std::string pName, int pChips, bool pWinner);
        ~Player();
    };
    player.cpp
    Code:
    #include "Player.h"#include <string>
    
    
    using namespace std;
    
    
    
    
    Player::Player(int pNumber, std::string pName, int pChips, bool pWinner) : name(pName), chips(pChips), Winner(pWinner)
    {
    
    
    }
    
    
    
    
    Player::~Player()
    {
    }
    lcr-rules-to-print.txt
    Code:
    Left Center Right (LCR) is a multi-player dice game with a minimum of three players, but no upper limit on the number of participants. The goal is to win all of the chips.
    
    The Dice
        * There are three dice rolled each turn. Each die has the letters L, C, and R on it along with dots on the remaining three sides. These dice determine where the player(s) chips will go.
        * For each L, the player must pass one chip to the player sitting to the left.
        * For each R, the player must pass one chip to the player sitting to the right.
        * For each C, the player must place one chip into the center pot and those chips are now out of play.
        * Dots are neutral and require no action to be taken for that die.
    
    
    The Chips
        * Each player will start with three chips.
        * If a player only has one chip, he/she rolls only one die. If a player has two chips left, he/she rolls two dice. Once a player is out of chips, he/she is still in the game (as he/she may get chips passed to him/her), but passes the dice to the next player.
    
    
    Winning the Game
        * The winner is the last player with chips.

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    In printRules, try this:
    Code:
            char ruleLine[1000];
    And get rid of the useless for loop.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  9. #9
    Registered User
    Join Date
    Feb 2018
    Posts
    6
    Quote Originally Posted by john.c View Post
    In printRules, try this:
    Code:
            char ruleLine[1000];
    And get rid of the useless for loop.
    Yeah, I put the for loop in there to try to use some escape clauses. I removed it and changed the line as you specified, but no change.

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    It works for me with that change. Post your current printRules function.

    The problem is that one of the lines in the rules file is longer than 254 characters.
    That sets the "badbit" which causes your while loop to go round and round doing nothing.

    EDIT!!!
    I forgot to mention that you also have to make this change:
    Code:
    rulesOfTheGame.getline(line, sizeof ruleLine);
    Last edited by john.c; 02-26-2018 at 10:41 AM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    See the FAQ as to why using eof() is a bad way to loop over a file.

    Try instead
    Code:
            while (rulesOfTheGame.getline(ruleLine, sizeof(ruleLine)))
            {
                cout << ruleLine << endl; // prints string to console
            }
    In addition to exiting the loop when the end of file was reached, it would also exit the loop on the afore-mentioned bad-bit as well.

    TBH, why aren't you using the std string getline method instead?
    Then you don't have to make random guesses as to how long a line might be.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    As Salem said, the best solution is to read the lines into a string instead of a char array. That way the string can expand as necessary.
    Code:
    void printRules() {
        ifstream rules("lcr-rules-to-print.txt");
        if (!rules) {
            cerr << "Unable to open the rules file\n";
            exit(EXIT_FAILURE);
        }
    
        string line;
        while (getline(rules, line))
            cout << line << endl;
    
        rules.close();
    }
    To use the char array you would need to do something like this:
    Code:
    void printRules() {
        ifstream rules("lcr-rules-to-print.txt");
        if (!rules) {
            cerr << "Unable to open the rules file\n";
            exit(EXIT_FAILURE);
        }
    
        char line[200];
        while (true) {
            rules.getline(line, sizeof line);
            if (rules.eof()) break;
            cout << line;
            if (rules.fail())
                rules.clear();
            else
                cout << endl;
        }
    
        rules.close();
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  13. #13
    Registered User
    Join Date
    Feb 2018
    Posts
    6
    Quote Originally Posted by Salem View Post
    See the FAQ as to why using eof() is a bad way to loop over a file.

    Try instead
    Code:
            while (rulesOfTheGame.getline(ruleLine, sizeof(ruleLine)))
            {
                cout << ruleLine << endl; // prints string to console
            }
    In addition to exiting the loop when the end of file was reached, it would also exit the loop on the afore-mentioned bad-bit as well.
    Aaah, I see. Thanks, that worked perfectly. I will definitely read the FAQ.

    Quote Originally Posted by Salem View Post
    TBH, why aren't you using the std string getline method instead?
    Then you don't have to make random guesses as to how long a line might be.
    I will look into that. We didn't cover getline in the class, but it's a beginner class so it's missing some depth.

    Thanks again for all the help, people.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 11-10-2013, 12:21 AM
  2. Replies: 3
    Last Post: 03-22-2013, 04:23 AM
  3. Replies: 3
    Last Post: 03-13-2013, 07:10 PM
  4. Return True or False, Not Print
    By BB18 in forum C Programming
    Replies: 5
    Last Post: 10-10-2004, 02:51 PM
  5. Completion Port and Multithreads :: MFC
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 11-06-2002, 11:37 PM

Tags for this Thread