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.