Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 了解seekg()和tellg()的内部工作原理_C++_File Io - Fatal编程技术网

C++ 了解seekg()和tellg()的内部工作原理

C++ 了解seekg()和tellg()的内部工作原理,c++,file-io,C++,File Io,我正在学习一个项目的文件I/O。使用seekg()和tellg()对我来说是必要的,所以我开始研究。在对代码进行故障排除时(因为文件没有按照我所希望的方式读取数据),我测试了以下代码: fileObj.seekg(fileObj.tellg(),std::ios::beg); 但是,这会导致一个无休止的循环。此代码在某个位置将导致无止境循环,但其他区域中的其他两条相同的行没有效果。tellg()应该是当前位置,因此将当前位置更改为当前位置不会产生任何效果。但情况显然不是这样,我想知道为什么我

我正在学习一个项目的文件I/O。使用seekg()和tellg()对我来说是必要的,所以我开始研究。在对代码进行故障排除时(因为文件没有按照我所希望的方式读取数据),我测试了以下代码:

fileObj.seekg(fileObj.tellg(),std::ios::beg); 
但是,这会导致一个无休止的循环。此代码在某个位置将导致无止境循环,但其他区域中的其他两条相同的行没有效果。tellg()应该是当前位置,因此将当前位置更改为当前位置不会产生任何效果。但情况显然不是这样,我想知道为什么我可以更有效地使用tellg()和seekg()

std::unordered_map <unsigned, Player> genRoster(String rosterFile)
{
    std::ifstream fileObj;
    fileObj.open(rosterFile.c_str(), std::ios::in);

    if (!fileObj.is_open())
    {
        std::cerr << "rosterFile could not be opened." << std::endl;
        exit(EXIT_FAILURE);
    }

    String teamName;
    teamName.getLine(fileObj,'\n',0);

    //skip the # of players line
    long long fileLocation;
    if(fileObj.tellg() != -1)
        fileLocation = fileObj.tellg() + 1;
    fileObj.seekg(fileLocation);

    std::unordered_map <unsigned, Player> roster;

    while(!fileObj.eof())
    {
        fileObj.seekg(fileObj.tellg(),std::ios::beg); //no effect
        unsigned ID;
        fileObj.seekg(fileObj.tellg(),std::ios::beg); //no effect
        String playerName;
        fileObj >> ID >> playerName;
        //fileObj.seekg(fileObj.tellg(),std::ios::beg); //endless loop!
        std::cout << "ID: " << ID << std::endl;
        std::cout << "name: " << playerName << std::endl;
        std::cout << "team: " << teamName << std::endl;

        //Player player(ID, playerName, teamName);  
        //roster.emplace(ID, player);
        // ...
        //The rest of the code is incomplete / irrelevant
    }
    return roster;
}
我使用的是我自己的字符串类,因此如果重载的>>运算符是问题的一部分,那么下面是实现:

std::istream& operator>>(std::istream& input, String& inputVar)
{
    inputVar.stringLen = 0;
    inputVar.stringVar = new char[inputVar.stringLen + 1];
    inputVar.stringVar[inputVar.stringLen] = '\0';

    long long lenCounter = 0;

    char inputChar;
    while (input.get(inputChar))
    {
        // end-of-input delimiter (change according to your needs)
        if (inputChar == '\n') break;

        // if buffer is exhausted, reallocate it twice as large
        if (lenCounter == inputVar.stringLen)
        {
            //this is needed for me bc i chose stringlen to be w/o null term.
            //so starts at 0. so *2 would do nothing
            if (inputVar.stringLen == 0) inputVar.stringLen++;
            inputVar.stringLen *= 2;
            char *newString = new char[inputVar.stringLen];
            strcpy(newString, inputVar.stringVar);
            delete[] inputVar.stringVar;
            inputVar.stringVar = newString;
        }
        // store input char
        inputVar.stringVar[lenCounter] = inputChar;

        lenCounter++;
    }
    inputVar.stringVar[lenCounter] = '\0';
    return input;
}
请原谅任何礼仪后的错误。让我知道,我会编辑。我一直在读堆栈溢出,但这是我的第一篇文章


多谢各位

您在文本模式下打开了该文件,并且对这些文件使用
seekg()
tellg()
将无法正常工作。尝试使用添加的
std::ios::binary
标志nstead打开文件。谢谢。这绝对是我的问题的根源。
std::istream& operator>>(std::istream& input, String& inputVar)
{
    inputVar.stringLen = 0;
    inputVar.stringVar = new char[inputVar.stringLen + 1];
    inputVar.stringVar[inputVar.stringLen] = '\0';

    long long lenCounter = 0;

    char inputChar;
    while (input.get(inputChar))
    {
        // end-of-input delimiter (change according to your needs)
        if (inputChar == '\n') break;

        // if buffer is exhausted, reallocate it twice as large
        if (lenCounter == inputVar.stringLen)
        {
            //this is needed for me bc i chose stringlen to be w/o null term.
            //so starts at 0. so *2 would do nothing
            if (inputVar.stringLen == 0) inputVar.stringLen++;
            inputVar.stringLen *= 2;
            char *newString = new char[inputVar.stringLen];
            strcpy(newString, inputVar.stringVar);
            delete[] inputVar.stringVar;
            inputVar.stringVar = newString;
        }
        // store input char
        inputVar.stringVar[lenCounter] = inputChar;

        lenCounter++;
    }
    inputVar.stringVar[lenCounter] = '\0';
    return input;
}