使用fstream读取包含空格和换行符在内的每个字符

时间:2008-09-22 19:26:06

标签: c++ newline spaces fstream

我想使用fstream来读取txt文件。

我正在使用inFile >> characterToConvert,但问题是这省略了任何空格和换行符。

我正在编写加密程序,所以我需要包含空格和换行符。

实现这个目标的正确方法是什么?

13 个答案:

答案 0 :(得分:48)

可能最好的方法是将整个文件的内容读入一个字符串,这可以使用ifstream的rdbuf()方法轻松完成:

std::ifstream in("myfile");

std::stringstream buffer;
buffer << in.rdbuf();

std::string contents(buffer.str());

然后,您可以使用常规字符串操作,因为您已从文件中获取所有内容。

虽然Tomek要求读取文本文件,但是同样的方法可以用于读取二进制数据,尽管在创建输入文件流时需要提供std :: ios :: binary标志。

答案 1 :(得分:22)

对于加密,最好以二进制模式打开文件。使用类似的东西将文件的字节放入向量中:

std::ifstream ifs("foobar.txt", std::ios::binary);

ifs.seekg(0, std::ios::end);
std::ifstream::pos_type filesize = ifs.tellg();
ifs.seekg(0, std::ios::beg);

std::vector<char> bytes(filesize);

ifs.read(&bytes[0], filesize);

编辑:根据评论修复了一个微妙的错误。

答案 2 :(得分:14)

我没有测试过这个,但我相信你需要清除“skip whitespace”标志:

inFile.unsetf(ios_base::skipws);

我对C ++流使用以下参考: IOstream Library

答案 3 :(得分:3)

以下c ++代码将读取整个文件......


#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main () 
{
  string line;
  ifstream myfile ("foo.txt");

  if (myfile.is_open()){

    while (!myfile.eof()){
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }
  return 0;
}

发布您的代码,我可以为您的问题提供更具体的帮助...

答案 4 :(得分:3)

istream层的许多好处是为简单类型ro和流提供基本格式化和解析。出于您描述的目的,这些都不是真正重要的,您只是将文件作为字节流感兴趣。

出于这些目的,您可能更好地使用filebuf提供的basic_streambuf接口。 'skip whitespace'行为是您不需要的istream接口功能的一部分。

filebuf是ifstream的基础,但直接使用它是完全有效的。

std::filebuf myfile;
myfile.open( "myfile.dat", std::ios_base::in | std::ios_base::binary );

// gets next char, then moves 'get' pointer to next char in the file
int ch = myfile.sbumpc();

// get (up to) the next n chars from the stream
std::streamsize getcount = myfile.sgetn( char_array, n );

另外看一下函数snextc(向前移动'get'指针然后返回当前的char),sgetc(获取当前char但不移动'get'指针)和sungetc(备份如果可能的话,“获取”一个位置的指针。

当你不需要istream类提供的任何插入和提取操作符并且只需要一个基本的字节接口时,通常streambuf接口(filebuf,stringbuf)比istream接口(ifstream,istringstream)更合适。

答案 5 :(得分:3)

std::ifstream ifs( "filename.txt" );

std::string str( ( std::istreambuf_iterator<char>( ifs ) ), 
                 std::istreambuf_iterator<char>()
               );

答案 6 :(得分:2)

您可以调用int fstream::get(),它将从流中读取单个字符。您也可以使用与get()执行相同操作的istream& fstream::read(char*, streamsize),只使用多个字符。给定的链接包括使用每种方法的示例。

我还建议以二进制模式读写。这允许从文件中正确读取和写入ASCII控制字符。否则,加密/解密操作对可能导致不相同的文件。为此,您可以使用ios::binary标志打开文件流。对于二进制文件,您希望使用read()方法。

答案 7 :(得分:2)

另一种更好的方法是使用istreambuf_iterator,示例代码如下:

ifstream inputFile("test.data");

string fileData(istreambuf_iterator<char>(inputFile), istreambuf_iterator<char>());

答案 8 :(得分:1)

对于加密,您应该使用read()。加密算法通常处理固定大小的块。哦,并以二进制模式打开(没有翻译frmo \ n \ r到\ n),将ios_base :: binary作为第二个参数传递给构造函数或open()调用。

答案 9 :(得分:0)

简单

#include <fstream>
#include <iomanip>


ifstream ifs ("file");
ifs >> noskipws

就是这样。

答案 10 :(得分:0)

ifstream ifile(path);
std::string contents((std::istreambuf_iterator<char>(ifile)), std::istreambuf_iterator<char>());
ifile.close();

答案 11 :(得分:0)

我还发现ifstream对象的get()方法也可以读取文件的所有字符,这些字符不需要取消设置std::ios_base::skipws。引自 C ++ Primer

  

一些未格式化的操作一次处理一个字节流。表17.19中描述的这些操作读取而忽略了空格。

这些操作列表如下: is.get()os.put()is.putback()is.unget()is.peek()

以下是最低工作代码

#include <iostream>
#include <fstream>
#include <string>

int main(){
    std::ifstream in_file("input.txt");

    char s;

    if (in_file.is_open()){
        int count = 0;
        while (in_file.get(s)){

            std::cout << count << ": "<< (int)s <<'\n';
            count++;
        }

    }
    else{
        std::cout << "Unable to open input.txt.\n";
    }
    in_file.close();

    return 0;
 }

输入文件(cat input.txt)的内容为

ab cd
ef gh

该计划的输出是:

0: 97
1: 98
2: 32
3: 99
4: 100
5: 10
6: 101
7: 102
8: 32
9: 103
10: 104
11: 32
12: 10

10和32是换行符和空格符的十进制表示。显然,所有人物都已被阅读。

答案 12 :(得分:-5)

正如Charles Bailey正确指出的那样,你不需要fstream的服务来读取字节。所以忘记这个iostream愚蠢,使用fopen / fread并完成它。 C stdio是C ++的一部分,你知道;)