[英]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()
.我有一个程序运行良好,直到我在使用std::getline()
之前关闭了一个文件。 The close(fileTest)
line causes the while loop to repeat forever without asking the user for input. close(fileTest)
行导致 while 循环永远重复而不要求用户输入。 It just skips the getline()
, even on the first loop.它只是跳过getline()
,即使在第一个循环中也是如此。
I spent about 2 hours trying to figure this out so I know all about the buffer and cin>>
behavior.我花了大约 2 个小时试图弄清楚这一点,所以我了解缓冲区和cin>>
行为。 I finally ended up commenting out lines before the getline()
call and found out what was happening.我终于在getline()
调用之前注释掉了行,并发现了发生了什么。
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.显然,我遇到了很多关于输入缓冲区的重复问题,我知道文件的工作方式类似,但我不明白为什么getline()
在我明确地从cin
请求数据时搞砸了,或者为什么关闭文件是触发它的原因。
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.在fileTest = (open(fileName, O_RDONLY)) < 0
中,在赋值之前执行比较,因为它具有更高的优先级。 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).因此fileTest
不会保存open
调用的结果,而是保存比较结果,该结果可能与标准输入/输出句柄之一(通常为 0、1、2)具有相同的值。 So subsequent close
will close standard input while handle returned by open
is lost.因此,随后的close
将关闭标准输入,而open
返回的句柄丢失。 Also result of open
should be checked against -1.还应根据 -1 检查open
结果。
So the rule of thumb is to never use result of assignment operator:所以经验法则是永远不要使用赋值运算符的结果:
auto const fileTest{::open(fileName, O_RDONLY)};
if (-1 == fileTest)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.