简体   繁体   中英

Closing file messes with std::getline() and cin?

I have a program that was working fine until I closed a file before using std::getline() . The close(fileTest) line causes the while loop to repeat forever without asking the user for input. It just skips the getline() , even on the first loop.

I spent about 2 hours trying to figure this out so I know all about the buffer and cin>> behavior. I finally ended up commenting out lines before the getline() call and found out what was happening.

Obviously I came across lots of duplicate questions about the input buffer and I know that files work similarly but I don't understand why getline() is messing up when I am explicitly requesting data from cin or why closing the file is what triggers it.

Any idea why this is happening or a workaround (other than just leaving the file open forever)?

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
//#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <iostream>
#include <string.h>
#include <limits>

using namespace std;

char *fileName;
struct stat fileStatus;

int main(int arc, char **argv)
{
    fileName = argv[1];
    string menuChoice = "1";

    //TODO: remove this. Testing only
    fileName = (char *)"test";

    //print message for no args
    if (fileName == NULL)
    {
        printf("NO file selected\nUsage: fileutil <filename>\n\n");
    }

    //Make sure we can actually open the file
    int fileTest;
    if (fileTest = (open(fileName, O_RDONLY)) < 0)
    {
        perror("Failed to open file");
        return (EXIT_FAILURE);
    }
    close(fileTest);  //THIS MESSES UP cin IF NOT COMMENTED OUT?????

    //main menu loop
    while (true)
    {
        //display the menu and handle options
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
        std::getline(cin, menuChoice);
        //view file contents
        if (menuChoice == "1")
        {
        }
        //display file info
        else if (menuChoice == "2")
        {
        }
        //change file permissions
        else if (menuChoice == "3")
        {
        }
        //copy file
        else if (menuChoice == "4")
        {            
        }
        //exit
        else if (menuChoice == "5")
        {
            printf("Thank you. Exiting program...\n\n");
            return (0);
        }
        //handle invalid responses
        else
            printf("Invalid response\n\n");
    }

    return 0;
} //end main

In fileTest = (open(fileName, O_RDONLY)) < 0 comparison is performed prior to assignment because it has higher precedence. So fileTest will not hold the result of open invocation but rather result of comparison which may be the same value as one of the standard input / output handles (which are typically 0, 1, 2). So subsequent close will close standard input while handle returned by open is lost. Also result of open should be checked against -1.

So the rule of thumb is to never use result of assignment operator:

auto const fileTest{::open(fileName, O_RDONLY)};
if (-1 == fileTest)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM