【问题标题】:Readfile is not reading the the blank spaces from my text file?Readfile 没有从我的文本文件中读取空格?
【发布时间】:2014-05-02 10:19:29
【问题描述】:

我正在阅读一个文本文件,发现它不会打印单词之间的空白字符。我想一次读取每个字符一个字符,然后将字符打印到输出窗口。读取将读取文件但不显示空格,我无法找出跳过空格的原因。

问题:为什么我的 read 没有读取测试文件中的空白字符?

当我找到一个空白字符时,我想打印空格这个词。

代码:

#include "stdafx.h"
#include "iostream"
#include<iostream>
#include<fstream>

void readTestFile()
{
    char ch;
    std::fstream fin("C:/Users/itpr13266/Desktop/myTest.txt", std::fstream::in);
    while (fin >> ch) {
        std::cout << "Letter: " << ch << std::endl;
          if (ch == ' ')  <-- should catch a blank spaces
          {
              std::cout << "Blank Space" << std::endl;
          }
          else  <-- Just write the letter
          {
              std::cout << ch << std::endl; 
          }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
   readTestFile();

   getchar();
   return 0;
}

测试文件:

  This is testing for fprintf...
  This is testing for fputs...

输出

 Letter: T
 T
 Letter: h
 h
 ...etc...

【问题讨论】:

  • 您的示例输出甚至没有显示问题。当它到达第一个空间时会发生什么?也可以打印出ch 的整数值。
  • 此操作fin &gt;&gt; ch 解析空白。它故意不抓取空格。

标签: c++


【解决方案1】:

您正在执行格式化输入,请使用未格式化输入

std::fstream::traits_type::int_type ch;
while((ch = fin.get()) != std::fstream::traits_type::eof()) {
    // ...
}

【讨论】:

  • 我更喜欢char ch; while ( fin.get(ch) ) {...}。不只是 eof 是这样测试的。
【解决方案2】:

默认情况下,流上的operator&gt;&gt; 在解析值之前会跳过任何前导空格。例如,这允许您使用int i,j,k; fin &gt;&gt; i &gt;&gt; j &gt;&gt; k; 读取输入30 60 95(否则读取j 将失败,因为在30 后面跟着一个空格,而不是整数)。

如果您还想读取空格,现在有两种选择:

  1. (首选):使用成员函数get() 对字符进行无格式读取。
  2. 指示流在阅读前不要吃空白:fin &gt;&gt; std::noskipws &gt;&gt; ch

【讨论】:

  • get() 是否只返回一个字符?
  • @user3376708:嗯,这取决于您调用的重载;-) 没有参数的将返回一个字符或 EOF。如果可能,引用 char 的那个将读取一个字符,并将其写入它的参数。其他重载读取直到遇到某个分隔符('\n',或作为参数传递),或超过给定大小,或无法读取更多字符(EOF 或流错误)。
【解决方案3】:

标准输入函数istream::operator&gt;&gt;() 在执行输入之前会跳过所有前导空格。如果您需要获取空间,可以使用以下几个选项:

  • std::noskipws

    通过设置std::ios_base::noskipws 标志,流将不会丢弃前导空格,ch 将被赋予每个连续字符的值。请注意,这仅在采用 char 的重载时才会成功(ch 将被赋予空格的值)。对于任何其他数据类型,这将不起作用:

    while (fin >> std::noskipws >> ch)
    {
        // ...
    }
    
  • std::istream::get()

    get() 是一个 UnformattedInputFunction 函数,因此不会预先解析输入。

    while (fin.get(ch))
    {
        // ...
    }
    
  • std::istreambuf_iterator&lt;&gt;

    您还可以使用迭代器直接使用缓冲区。 std::istreambuf_iterator&lt;&gt; 也不解析输入:

    std::copy(std::istreambuf_iterator<char>{fin},
              std::istreambuf_iterator<char>{},
              std::ostreambuf_iterator<char>{std::cout},
    

【讨论】:

  • 它真的不适用于任何其他数据类型吗?我没有尝试,但我认为对于string 它也应该成功(尽管可能不是预期的结果)。
  • @celtschk 除非您自己清除空白,否则它不会起作用。 Even with std::string it doesn't work.
  • 好的,我试过了,g++ 同意你的观点。但是我很惊讶,因为我希望它能够成功读取一个空字符串(顺便说一句,您的 ideone 不会测试成功或失败,只是字符串是空的,成功读取也是如此) .
  • @celtschk 不能,因为空格是格式化运算符输入的分隔符。您可以使用std::getline(),它会起作用。 (关于。如果您检查good() 的流状态,它将返回false,因为0 个字符被提取到str,导致failbit 被设置为流状态。)
  • 空字符串 isstd::string 的有效值,并且输入流包含一个空字符串,后跟一个分隔符(这意味着第一个字符是一个分隔符)。
【解决方案4】:

详细了解不同的iostream 方法。特别是,您使用的是istream's operator>>。仔细注意它是如何设计的;它使用空格作为分隔符并且不存储空格。

如果您想从流(例如文件流)中读取每个char,则不应使用&gt;&gt;,而应考虑使用istream::get()

// stream is an istream, such as cin or ifstream
char ch;
while (ch = stream.get()) { }

【讨论】:

    【解决方案5】:

    这对我有用。我将它设置在一个函数中,以便您可以复制粘贴。它检测空间,以及线的变化。我用 ASCII 艺术试了一下,效果很好。

    void print2()
        {
        char ch;
        std::fstream myStream("GameOver.txt", std::fstream::in);
        while (myStream.get(ch))
            {
                std::cout << ch;        
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多