fstream
を使用して、txtファイルを読み取りたいと思いました。
私は使っている inFile >> characterToConvert
、ただし問題は、スペースと改行が省略されることです。
暗号化プログラムを書いているので、スペースと改行を含める必要があります。
これを達成するための適切な方法は何でしょうか?
おそらく最良の方法は、ファイルのコンテンツ全体を文字列に読み込むことです。これは、ifstreamの rdbuf()
メソッドを使用して非常に簡単に実行できます。
std::ifstream in("myfile");
std::stringstream buffer;
buffer << in.rdbuf();
std::string contents(buffer.str());
ファイルからすべてを取得したので、通常の文字列操作を使用できます。
Tomek はテキストファイルの読み取りについて尋ねていましたが、入力ファイルストリームの作成時にstd :: ios :: binaryフラグを提供する必要がありますが、同じアプローチがバイナリデータの読み取りに対して機能します。
暗号化の場合は、ファイルをバイナリモードで開くことをお勧めします。次のようなものを使用して、ファイルのバイトをベクターに入れます。
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);
編集:コメントに従って微妙なバグを修正しました。
これはテストしていませんが、「空白をスキップ」フラグをクリアする必要があると思います。
inFile.unsetf(ios_base::skipws);
C++ストリームには次のリファレンスを使用します。 IOstream Library
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」をバックアップする)可能な場合は1ポジションずつポインタを移動します)。
Istreamクラスが提供する挿入演算子と抽出演算子を必要とせず、基本的なバイトインターフェイスのみが必要な場合、多くの場合、streambufインターフェイス(filebuf、stringbuf)がistreamインターフェイス(ifstream、istringstream)よりも適切です。
std::ifstream ifs( "filename.txt" );
std::string str( ( std::istreambuf_iterator<char>( ifs ) ),
std::istreambuf_iterator<char>()
);
次の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;
}
あなたのコードを投稿すると、あなたの問題に対するより具体的な助けを与えることができます...
int fstream::get()
を呼び出すことができます。これは、ストリームから単一の文字を読み取ります。 istream& fstream::read(char*, streamsize)
を使用することもできます。これは、複数の文字に対してget()
と同じ操作を行います。指定されたリンクには、各メソッドの使用例が含まれています。
また、バイナリモードで読み書きすることをお勧めします。これにより、ASCII制御文字がファイルから適切に読み取られ、書き込まれます。 _ios::binary
_ flag。バイナリファイルでは、read()
メソッドを使用します。
別のより良い方法は、istreambuf_iteratorを使用することです。サンプルコードは次のとおりです。
ifstream inputFile("test.data");
string fileData(istreambuf_iterator<char>(inputFile), istreambuf_iterator<char>());
暗号化には、おそらく read() を使用する必要があります。暗号化アルゴリズムは通常、固定サイズのブロックを扱います。ああ、バイナリモード(\ n\rから\ nへの変換なし)で開くには、コンストラクターまたはopen()呼び出しの2番目のパラメーターとしてios_base :: binaryを渡します。
シンプル
#include <fstream>
#include <iomanip>
ifstream ifs ("file");
ifs >> noskipws
それで全部です。
ifstream ifile(path);
std::string contents((std::istreambuf_iterator<char>(ifile)), std::istreambuf_iterator<char>());
ifile.close();
また、ifstreamオブジェクトの get() メソッドは、ファイルのすべての文字を読み取ることができることもわかります。これは、未設定std::ios_base::skipws
を必要としません。 C++ Primerからの引用:
フォーマットされていない操作のいくつかは、一度に1バイトのストリームを処理します。表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は、改行文字とスペース文字の10進数表現です。明らかに、すべての文字が読み取られました。