33

I wanted to use fstream to read a txt file.

I am using inFile >> characterToConvert, but the problem is that this omits any spaces and newline.

I am writing an encryption program so I need to include the spaces and newlines.

What would be the proper way to go about accomplishing this?

4

13 回答 13

48

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

std::ifstream in("myfile");

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

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

既然您已经从文件中获得了所有内容,那么您就可以使用常规的字符串操作了。

Tomek询问读取文本文件时,同样的方法也适用于读取二进制数据,尽管在创建输入文件流时需要提供 std::ios::binary 标志。

于 2008-09-22T20:03:51.143 回答
22

For encryption, you're better off opening your file in binary mode. Use something like this to put the bytes of a file into a vector:

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);

Edit: fixed a subtle bug as per the comments.

于 2008-09-22T19:36:35.313 回答
14

I haven't tested this, but I believe you need to clear the "skip whitespace" flag:

inFile.unsetf(ios_base::skipws);

I use the following reference for C++ streams: IOstream Library

于 2008-09-22T19:37:02.987 回答
4
std::ifstream ifs( "filename.txt" );

std::string str( ( std::istreambuf_iterator<char>( ifs ) ), 
                 std::istreambuf_iterator<char>()
               );
于 2011-04-13T08:24:34.233 回答
3

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

出于这些目的,您最好只使用 filebuf 提供的 basic_streambuf 接口。“跳过空白”行为是您不需要的 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”指针向前移动,然后返回当前字符)、sgetc(获取当前字符但不移动“get”指针)和 sungetc(备份“get”如果可能,将指针移到一个位置)。

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

于 2008-09-22T21:29:25.417 回答
3

The following c++ code will read an entire file...


#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;
}

post your code and I can give you more specific help to your problem...

于 2008-09-22T19:31:31.220 回答
2

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

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

于 2008-09-22T19:55:20.510 回答
2

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

ifstream inputFile("test.data");

string fileData(istreambuf_iterator<char>(inputFile), istreambuf_iterator<char>());
于 2012-08-24T03:43:20.397 回答
1

对于加密,您可能应该使用read()。加密算法通常处理固定大小的块。哦,要以二进制模式打开(不从 \n\r 转换为 \n),请将 ios_base::binary 作为第二个参数传递给构造函数或 open() 调用。

于 2008-09-22T19:45:22.093 回答
0

简单的

#include <fstream>
#include <iomanip>


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

就这样。

于 2008-09-23T06:05:15.783 回答
0
ifstream ifile(path);
std::string contents((std::istreambuf_iterator<char>(ifile)), std::istreambuf_iterator<char>());
ifile.close();
于 2012-07-21T08:58:32.680 回答
0

我还发现 ifstream 对象的get()方法也可以读取文件的所有字符,不需要 unset 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 是换行符和空格字符的十进制表示。显然,所有字符都已被读取。

于 2017-06-15T15:36:26.840 回答
-5

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

于 2008-09-22T22:12:20.697 回答