【发布时间】:2010-09-12 03:07:38
【问题描述】:
我想用fstream 来读取一个txt文件。
我正在使用inFile >> characterToConvert,但问题是它省略了任何空格和换行符。
我正在编写一个加密程序,所以我需要包含空格和换行符。
完成此任务的正确方法是什么?
【问题讨论】:
标签: c++ newline spaces fstream
我想用fstream 来读取一个txt文件。
我正在使用inFile >> characterToConvert,但问题是它省略了任何空格和换行符。
我正在编写一个加密程序,所以我需要包含空格和换行符。
完成此任务的正确方法是什么?
【问题讨论】:
标签: c++ newline spaces fstream
我也发现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 是换行符和空格字符的十进制表示。很明显,所有字符都被读取了。
【讨论】:
【讨论】:
另一种更好的方法是使用istreambuf_iterator,示例代码如下:
ifstream inputFile("test.data");
string fileData(istreambuf_iterator<char>(inputFile), istreambuf_iterator<char>());
【讨论】:
ifstream ifile(path);
std::string contents((std::istreambuf_iterator<char>(ifile)), std::istreambuf_iterator<char>());
ifile.close();
【讨论】:
std::ifstream ifs( "filename.txt" );
std::string str( ( std::istreambuf_iterator<char>( ifs ) ),
std::istreambuf_iterator<char>()
);
【讨论】:
对于加密,您最好以二进制模式打开文件。使用类似这样的东西将文件的字节放入向量中:
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);
编辑:根据 cmets 修复了一个微妙的错误。
【讨论】:
简单
#include <fstream>
#include <iomanip>
ifstream ifs ("file");
ifs >> noskipws
就是这样。
【讨论】:
正如 Charles Bailey 正确指出的那样,您不需要 fstream 的服务来读取字节。所以忘记这个 iostream 愚蠢,使用 fopen/fread 并完成它。 C stdio 是 C++ 的一部分,你知道 ;)
【讨论】:
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(备份如果可能,将指针“获取”一个位置)。
当您不需要 istream 类提供的任何插入和提取运算符而只需要一个基本的字节接口时,通常 streambuf 接口(filebuf、stringbuf)比 istream 接口(ifstream、istringstream)更合适.
【讨论】:
您可以调用int fstream::get(),它将从流中读取单个字符。您还可以使用istream& fstream::read(char*, streamsize),它与get() 执行相同的操作,只是在多个字符上。给定的链接包括使用每种方法的示例。
我还建议以二进制模式进行读写。这允许正确地从文件读取和写入 ASCII 控制字符。否则,加密/解密操作对可能会产生不相同的文件。为此,您使用ios::binary 标志打开文件流。对于二进制文件,您想使用read() 方法。
【讨论】:
对于加密,您可能应该使用read()。加密算法通常处理固定大小的块。哦,要以二进制模式打开(没有从 \n\r 到 \n 的转换),请将 ios_base::binary 作为第二个参数传递给构造函数或 open() 调用。
【讨论】:
【讨论】:
以下 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;
}
发布您的代码,我可以为您的问题提供更具体的帮助...
【讨论】: