【问题标题】:Reading a text file in c++在 C++ 中读取文本文件
【发布时间】:2012-10-27 16:56:46
【问题描述】:
string numbers;
string fileName = "text.txt";


ifstream inputFile;
inputFile.open(fileName.c_str(),ios_base::in);
inputFile >> numbers;
inputFile.close();
cout << numbers;

而我的 text.txt 文件是:

1    2    3    4    5

基本上是一组由制表符分隔的整数。

问题是程序只读取 text.txt 文件中的第一个整数,而由于某种原因忽略了其余的整数。如果我删除整数之间的制表符,它可以正常工作,但是它们之间有制表符,它将不起作用。这是什么原因造成的?据我所知,它应该忽略任何空白字符还是我弄错了?如果是这样,有没有更好的方法从文本文件中获取这些数字?

【问题讨论】:

  • 它只忽略字符前的空格。如果要包含空格,请使用 std::getline。如果您希望它们作为数字,std::vector&lt;int&gt;(std::istream_iterator&lt;int&gt;(inputFile), std::istream_iterator&lt;int&gt;()) 就可以了。

标签: c++ text input


【解决方案1】:

当读取格式化字符串时,输入操作符从忽略前导空格开始。然后它将非空白字符读取到第一个空格并停止。非空白字符存储在std::string 中。如果在流到达文件末尾之前只有空白字符(或某些错误),则读取失败。因此,您的程序会读取一个“单词”(在本例中是一个数字)并停止读取。

不幸的是,您只说了您在做什么以及您的方法存在什么问题(您的问题描述未能涵盖首先读取输入失败的情况)。以下是您可能想尝试的几件事:

  1. 如果您想阅读多个单词,可以这样做,例如,通过阅读所有单词:

    std::vector<std::string> words;
    std::copy(std::istream_iterator<std::string>(inputFile),
              std::istream_iterator<std::string>(),
              std::back_inserter(words));
    

    这将从inputFile 中读取所有单词并将它们作为std::strings 的序列存储在向量words 中。由于您的文件包含数字,您可能希望将 std::string 替换为 int 以以易于访问的形式读取数字。

  2. 如果您想阅读一行而不是一个单词,您可以改用std::getline()

    if (std::getline(inputFile, line)) { ... }
    

    如果你想读取多行,你可以把这个操作放到一个循环中:不幸的是,没有像单词那样读取一系列行的read-made方法。

  3. 如果您想将整个文件(而不仅仅是第一行)读入文件,您也可以使用std::getline(),但您需要知道文件中没有出现的一个字符值,例如,空值:

    if (std::getline(inputFile, text, char()) { ... }
    

    这种方法将“行”视为一个字符序列,直到一个空字符。您也可以使用任何其他字符值。如果你不能确定字符值,你可以使用 std::string 的构造函数来读取整个文件:

    std::string text((std::istreambuf_iterator<char>(inputFile)),
                     std::istreambuf_iterator<char>());
    

    请注意,不幸的是,第一个参数周围的额外括号是必要的(如果您使用的是 C++ 2011,则可以通过使用大括号而不是括号来避免它们)。

【讨论】:

  • 问题是当我使用上面提到的方法使用带有迭代器的字符串构造函数读取整个文件时,我使用的字符串似乎太小而无法包含所有 100 个数字。它仅包含该组的最后 19 个数字。当我尝试使用 getLine() 方法时也遇到了这个问题。据我记得一个字符串会在需要时自动调整大小,但这似乎对我不起作用。
  • 构造函数肯定会读取整个文件!我什至想不出一个合理的理由来只阅读输入的尾部!你能展示你在做什么吗?
  • ifstream inputFile("text.txt");字符串 s((istreambuf_iterator(inputFile)), istreambuf_iterator());我试过这个,但显然我的问题的原因是由于我的 IDE 中的一个错误。它可能会捕获整行并将其放入一个字符串中没有问题,但是当它显示字符串时会出现问题。我的 IDE(netbeans)输出面板能够显示一定大小的字符串。在打印包含这些数字的字符串之前,如果我使用 cout 打印一些其他内容,它们只是相互重叠而不是继续新行。
【解决方案2】:

使用 getline 进行阅读。

string numbers;
if (inputFile.is_open())//checking if open
{
      getline (inputFile,numbers); //fetches entire line into string numbers
      inputFile.close();
}

【讨论】:

  • 我尝试使用它,但这次它玩的是一个与我的文本文件不同的字符串派对。我的文本文件是这个 3 5 2 13 4 5 6 7 1 7 5 13 12 2 7 12 3 1 4 5 1 10 5 1 14 6 4 1 7 2 4 9 17 5 6 2 7 21 8 1 6 17 32 8 5 4 1 4 3 34 7 6 85 20 2 6 13 6 72 2 1 1 97 3 1 9 5 48 1 8 3 23 3 34 16 1 51 192 4 6 6 25 2 12 3 3 3 4 219 5 12 53 8 73 4 17 14 7 8 22 我得到的是 12 53 87 73 46 17 14 792 819 22 似乎是我的文本文件的最后一点,但略有不同
【解决方案3】:

您的程序的行为与您的描述完全相同:inputFile &gt;&gt; numbers; 只需提取输入文件中的第一个整数,因此如果您取消制表符,inputFile&gt;&gt; 将提取数字 12345,而不是 5 个五个数字 @987654324 @。

更好的方法:

vector< int > numbers;
string fileName = "text.txt";
ifstream inputFile;
inputFile.open(fileName.c_str(),ios_base::in);
char c;
while (inputFile.good())     // loop while extraction from file is possible
{
    c = inputFile.get();       // get character from file
    if ( inputFile.good() and c!= '\t' and c!=' ' ) // not sure of tab and space encoding in C++
    {
      numbers.push_back( (int) c);
    }
}
inputFile.close();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2015-05-16
    相关资源
    最近更新 更多