【问题标题】:Having trouble reading items from a file (C++)从文件中读取项目时遇到问题 (C++)
【发布时间】:2015-11-29 03:57:13
【问题描述】:

所以,我无法将文本文件中的最后一项读入字符串对象。

我创建了一个名为“Car”的类,我应该从文件中读取“Car”对象的所有参数,但它不会注册最后一个。

ifstream 对象是“数据”

变量是:

string carType;
string reportingMark;
int carNumber;
string kind;
bool loaded;
string destination;

文本文件中的行内容为:

汽车 CN 819481 维修假无

这就是我现在拥有的:

getline(data, ignore); // ignores the header line
data >> carType >> reportingMark >> carNumber >> kind >> loaded;
while (data.peek() == ' ') // this and the next lines were the suggestions of the teacher to bypass the spaces (of which there are more than it will display here)
   data.get();
getline(data, destination);

因此,它将读取除“目标”部分之外的所有内容。

【问题讨论】:

  • 我认为我们需要在您的代码和示例文件中查看更多上下文。
  • 给你的“ifstream”对象一个while循环怎么样
  • 详细了解destination 变量。它最终输出什么?是不是少了个字母?是空的吗?引发错误?奇怪的符号?

标签: c++ fstream getline


【解决方案1】:

问题出在这部分:

data >> carType >> reportingMark >> carNumber >> kind >> loaded;

在这里,您尝试从流中提取布尔变量 loaded。你希望阅读false 会起作用,但它不会。它只接受01

相反,未能读取布尔变量将切换流的err 位,这会导致读取失败后的所有其他内容。

要检查这一点,如果您在该行之后立即执行data.peek(),您将收到-1,表示没有有效输入。

要解决此问题,您需要将存储信息的方式更改为存储 0/1 而不是 true/false,或者更好:

在读取数据之前执行:data << boolalpha。这将使流将true/false 解释为0/1

【讨论】:

  • 哦,我什至没有注意到布尔变量!
  • 我不敢相信,这就是它一直拖累它的原因!谢谢大佬!
【解决方案2】:

检查所有 IO 操作的返回值总是好的。如果您添加错误检查,您可能能够定位问题并找到解决方案。

if (!getline(data, ignore)) // ignores the header line
{
   std::cerr << "Unable to read the header\n";
   exit(EXIT_FAILURE);
}

if ( !(data >> carType >> reportingMark >> carNumber >> kind >> loaded))
{
   std::cerr << "Unable to read the data\n";
   exit(EXIT_FAILURE);
}

while (data.peek() == ' ') // this and the next lines were the suggestions of the teacher to bypass the spaces (of which there are more than it will display here)
   data.get();

if ( !getline(data, destination) )
{
   std::cerr << "Unable to read the rest of the line\n";
   exit(EXIT_FAILURE);
}

【讨论】:

    【解决方案3】:

    代码似乎是正确的;除了我认为没有必要放置

    while (data.peek() == ' ') 数据.get();

    getline(数据,目的地);

    部分读取目的地。相反,您可以简单地将其读取为数据 >> 目标。 此外,请确保您的输入文件正确打开,通过检查

    if(data.isOpen()){//cout something}

    我希望这会有所帮助! :)

    【讨论】:

    • 如果destination 可以是多个单词(以空格分隔),那么这还不够。
    • @VillasV 听起来很合法!
    【解决方案4】:

    给你的“ifstream”对象一个while循环怎么样,像这样

        ifstream ifstreamObject;
            ifstreamObject.open("car.txt");
    
    
    cout << "carType"<< ' '<< "reportingMark" << ' '<< "carNumber" <<' '<< "kind" <<' '<< "loaded"<<' '<<"destination"<< endl;
               while(ifstreamObject >> carType >> reportingMark >> carNumber >> kind >> loaded >> destination )
               {       cout <<"---------------------------------------------------------------------------"<<endl;
                       cout << carType<< ' '<< reportingMark << ' '<< carNumber <<' '<< kind <<' '<< loaded<<' '<<destination<< endl;
               }
    

    【讨论】:

      【解决方案5】:

      如果我是你,我会尝试使用 strtok 函数从文件中读取。

      如果您愿意,可以阅读本文以获取更多信息strtok function

      我最近完成了这项任务,我使用了 strtok,因为它允许将文件的每一行拆分成一个单词列表。此外,它还可以让您避免分配空格等标点符号。(所以我发现它非常有用)

      我的例子:我想从一个文件中读取一些角色数据,比如它的种族、职业、生命值、攻击和防御。

      我文件的每一行都是这样的:Human/soldier/15/7/7

      因此,我定义了一个存储 strtok 函数返回值的 char 指针和一个存储读取字的 char 指针,直到找到您之前考虑过的分隔符。 (在本例中:'/')

      char* position = strtok(file, '/');
      char* character_info = new char[size];
      

      因此,您将该行存储在 character_info 中,并在每次迭代中检查位置值,直到您完成读取文件。

      while(position != NULL){
        // store position value
        // call again strtok
      }
      

      我希望它会有所帮助! =)

      干杯

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-28
        • 2017-07-21
        • 1970-01-01
        • 2015-02-19
        • 1970-01-01
        • 2015-03-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多