【问题标题】:trouble reading from file in c++在 C++ 中读取文件时遇到问题
【发布时间】:2017-07-21 17:29:53
【问题描述】:

我正在尝试读取一个文件,其中第一行是整数,下一行是字符串(我必须将其读入 char 数组)。 我在输入流对象上使用 >> 运算符来读取整数,然后我使用 .get() 方法和 .ignore() 方法将下一行读入 char 数组,但是当我尝试读入char 数组我得到一个空白字符串 我不知道为什么我得到一个空白字符串,你知道为什么会这样吗?

这是我用来从文件中读取的代码:

BookList::BookList()
{
    //Read in inventory.txt and initialize the booklist
    ifstream invStream("inventory.txt", ifstream::in);
    int lineIdx = 0;
    int bookIdx = 0;
    bool firstLineNotRead = true;

    while (invStream.good()) {
        if (firstLineNotRead) {
            invStream >> listSize;
            firstLineNotRead = false;
            bookList = new Book *[listSize];
            for (int i = 0; i < listSize; i++) {
                bookList[i] = new Book();
            }

        } else {
            if (lineIdx % 3 == 0) {
                char tempTitle[200];
                invStream.get(tempTitle, 200, '\n');
                invStream.ignore(200, '\n');
                bookList[bookIdx] = new Book();
                bookList[bookIdx]->setTitle(tempTitle);
            } else if (lineIdx % 3 == 1) {
                int bookCnt;
                invStream >> bookCnt;
                bookList[bookIdx]->changeCount(bookCnt);
            } else if (lineIdx % 3 == 2) {
                float price;
                invStream >> price;
                bookList[bookIdx]->setPrice(price);
                bookIdx++;
            }
            lineIdx++;
        }
    }
}

所以 listSize 是从文件的第一行读取的第一个整数,而 tempTitle 是一个临时缓冲区,用于从文件的第二行读取字符串。但是当我执行 invStream.get() 和 invStream.ignore() 时,我看到 tempTitle 字符串是空白的。为什么?

【问题讨论】:

  • 想想第一行的整数之后的第一个\n
  • 提供示例文件?
  • 你为什么不用getline()

标签: c++ string file io


【解决方案1】:

从文件中读取第一个整数后,文件中有一个换行符等待读取。

然后你继续告诉它读取一个字符串。它是这样做的——将换行解释为字符串的结尾,所以你读取的字符串是空的。

在那之后,一切都变得不平衡了,所以其余的阅读几乎肯定会失败(至少无法达到你想要的)。

顺便说一句,我会以完全不同的方式完成这样的任务——可能更像这样:

#include <iostream>
#include <vector>
#include <bitset>
#include <string>
#include <conio.h>

class Book {
    std::string title;
    int count;
    float price;
public:

    friend std::istream &operator>>(std::istream &is, Book &b) {
        std::getline(is, title);
        is >> count;
        is >> price;
        is.ignore(100, '\n');
        return is;
    }
};

int main() {
    int count;

    std::ifstream invStream("inventory.txt");

    invStream >> count;
    invStream.ignore(200, '\n');

    std::vector<Book> books;

    Book temp;

    for (int i = 0; i<count && invStream >> temp;)
        books.push_back(temp);
}

【讨论】:

    【解决方案2】:

    你很可能通过交换行来修复你的程序

    invStream.get(tempTitle, 200, '\n');
    invStream.ignore(200, '\n');
    

    即使用:

    invStream.ignore(200, '\n');
    invStream.get(tempTitle, 200, '\n');
    

    作为一般准则,如果文件内容的格式使文本行具有特定含义,则您将更容易逐行读取文件内容并处理每一行的内容。

    std::string line;
    while (getline(invStream, line)) {
    
       if (firstLineNotRead) {
          // Extract the listSize from the first line using 
          // a istringstream.
          std::istringstream str(line);
          str >> listSize;
          firstLineNotRead = false;
          bookList = new Book *[listSize];
          for (int i = 0; i < listSize; i++) {
             bookList[i] = new Book();
          }
       }
    
       else {
          // The line has already been read.
          // Use it.
    
          ...
    
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-09-28
      • 1970-01-01
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多