简体   繁体   English

关闭文件与 std::getline() 和 cin 混乱?

[英]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.

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