从文件读入会产生意外的输出

时间:2016-10-10 05:03:45

标签: c++

我正在从一个文件中读取并解析来自命令行参数的数据来完成作业。我跑到墙上,我不知道问题是什么,我希望能得到一些关于我所缺少的建议。

这样组成数据文件;在第一行,它有总行数。对于之后的每一行,它是由|分隔的一行字符串字符。我需要' |'因为我想将我的字符串拆分为子字符串。

以下是输入文件的示例。

3
league of legends|Teemo|Master Yi|Vayne
apple|samsung|smart phone|smart watch
overwatch|d.va|junkrat|Reinhart

这是我的代码。

int main( int argc, char* const argv[] )
{

 //change string to char* so I can check through each char to see if the 
 //thing I read in is '|' character.
 String Data = (argv[1]);
 ifstream fin (Data.c_str());

 //check whether the file is open.
 if ( !fin.is_open() )
 {
    cout << "Could not open file" << endl;
 }

 else
 {
     int dataLines;
     char dataBuffer[100];

     //The first integer I read in will be how many lines I will loop through
     fin >> dataLines;
     //ignore the new line character and do not include it in the count of
     //dataLines.
     fin.ignore();

     //use noskipws so I can recognize whitespaces.
     fin >> noskipws >> dataBuffer;

     //TEST CODE: COMMENTED OUT FOR NOW.
     //cout<<dataBuffer<<endl;

     //loop for the number of lines
     for(int i = 0; i < dataLines; i++)
     {

         fin.getline(dataBuffer, 100);
         //print the buffer for checking
         cout<<dataBuffer<<endl;
     }
 }
 //close the file.
 fin.close();
 return 0;

}

结果应该是这样的。

league of legends|Teemo|Master Yi|Vayne
apple|samsung|smart phone|smart watch
overwatch|d.va|junkrat|Reinhart

实际结果如下所示

of legends|Teemo|Master Yi|Vayne
apple|samsung|smart phone|smart watch
overwatch|d.va|junkrat|Reinhart

我从缓冲区读到的第一个单词已经消失了。 &#34;联赛&#34;是缺少的那个,我试着通过在我的代码中指定的位置插入测试代码来查看问题所在。使用给定的测试代码,我的输出是

league
of legends|Teemo|Master Yi|Vayne
apple|samsung|smart phone|smart watch
overwatch|d.va|junkrat|Reinhart

所以问题是在使用noskipws读取文件和在dataLine上循环的forloop之间。在forloop之前,我的缓冲区是联盟。然而,一旦我进入循环,它就会通过并直接进入

我在这里缺少什么?什么是可能的解决方案?

3 个答案:

答案 0 :(得分:1)

主要问题:

render()

做两件事。 1. fin >> noskipws >> dataBuffer; 关闭自动跳过空格,因为OP正在读取流而不必要。 2. >> noskipws从流中读取第一个单词,在这种情况下使用单词&#34; league&#34;

解决方案:不要这样做。

其他问题:

>> dataBuffer

将完全忽略一个字符。但是如果有人在伯爵之后离开了一个看不见的空间呢?而是使用

fin.ignore();

确保线的其余部分以其完整性消耗。

fin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

为什么让自己受苦?而是使用

char dataBuffer[100];

建议:

使用std::stringstreamstd::getline来标记&#39; |&#39;

上的行
std::string dataBuffer;

答案 1 :(得分:0)

您不需要以下一行:

fin >> noskipws >> dataBuffer;

在RHEL 7.1上使用g ++ 4.8.3 2进行测试

答案 2 :(得分:0)

感谢用户4581301.它正确读取数据并用&#39; |&#39;字符。现在我可以将数据存储到类中了。

对于可能遇到同样问题的人,这是代码的修复版本。

int main( int argc, char* const argv[] )
{

String Data = (argv[1]);
ifstream fin (Data.c_str());

if ( !fin.is_open() )
{
   cout << "Could not open file" << endl;
}

else
{
    int dataLines;
    char dataBuffer[100];

    fin >> dataLines;
    fin.ignore();

    for(int i = 0; i < dataLines; i++)
    {
        while(fin.getline(dataBuffer, 100, '|'))
        {
            cout<<dataBuffer<<endl;// check to see if it reads in correctly.
        }
    }
}
fin.close();
return 0;
}