




Следующий код на 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;
}
опубликуйте свой код, и я могу дать вам более конкретную помощь по вашей проблеме ...
Для шифрования лучше открывать файл в двоичном режиме. Используйте что-то вроде этого, чтобы поместить байты файла в вектор:
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);
Обновлено: исправлена небольшая ошибка в соответствии с комментариями.
Извините, это небольшая ошибка. Вызывается перегрузка seekg, которая принимает только смещение, и в итоге вы читаете только два байта (значение std :: ios: end). Вы должны вызывать seekg (0, std :: ios :: end) и seekg (0, std :: ios :: begin).
Я не тестировал это, но считаю, что вам нужно снять флаг «пропускать пробелы»:
inFile.unsetf(ios_base::skipws);
Я использую следующую ссылку для потоков C++: Библиотека IOstream
да, обязательно нужно добавить это, если вы хотите читать двоичные данные, так как по умолчанию он включен.
Мне тоже нужен этот Кроме того для флага ios :: binary
Для шифрования вам, вероятно, следует использовать читать(). Алгоритмы шифрования обычно работают с блоками фиксированного размера. О, и чтобы открыться в двоичном режиме (без преобразования из \ n \ r в \ n), передайте ios_base :: binary в качестве второго параметра для вызова конструктора или open ().
Вы можете вызвать int fstream::get(), который прочитает один символ из потока. Вы также можете использовать istream& fstream::read(char*, streamsize), который выполняет ту же операцию, что и get(), только для нескольких символов. Приведенные ссылки включают примеры использования каждого метода.
Я также рекомендую читать и писать в двоичном режиме. Это позволяет правильно читать и записывать в файлы управляющие символы ASCII. В противном случае пара операций шифрования / дешифрования может привести к получению неидентичных файлов. Для этого вы открываете файловый поток с флагом ios::binary. С двоичным файлом вы хотите использовать метод read().
Вероятно, лучший способ - прочитать все содержимое файла в строке, что очень легко сделать с помощью метода ifstream rdbuf():
std::ifstream in("myfile");
std::stringstream buffer;
buffer << in.rdbuf();
std::string contents(buffer.str());
Теперь, когда у вас есть все из файла, вы можете использовать обычные манипуляции со строками.
Пока Томек спрашивал о чтении текстового файла, тот же подход будет работать для чтения двоичных данных, хотя при создании потока входного файла необходимо указать флаг std :: ios :: binary.
Как я могу проголосовать за это больше? Это сэкономило бы мне ЧАСЫ программирования ... Вы были бы потрясены количеством советов Плохо (даже опытных пользователей стека), которые существуют на этом сайте.
Большим преимуществом уровня istream является обеспечение базового форматирования и синтаксического анализа для простых типов как из потока, так и из потока. Для целей, которые вы описываете, все это на самом деле не важно, и вас просто интересует файл как поток байтов.
Для этой цели вам может быть лучше просто использовать интерфейс basic_streambuf, предоставляемый filebuf. Поведение «пропустить пробелы» - это часть функциональности интерфейса 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 (сохраняет резервную копию get) указатель на одну позицию, если это возможно).
Если вам не нужны какие-либо операторы вставки и извлечения, предоставляемые классом istream, и нужен только базовый байтовый интерфейс, часто интерфейс streambuf (filebuf, stringbuf) более подходит, чем интерфейс istream (ifstream, istringstream).
Как правильно заметил Чарльз Бейли, вам не нужны службы fstream только для чтения байтов. Так что забудьте об этой глупости iostream, используйте fopen / fread и покончим с этим. Как вы знаете, C stdio - это часть C++;)
Но при использовании потоков поток не должен быть просто файлом. Это может быть строка, сокет или что угодно еще. streambuf_iterator <>
Я согласен, но OP конкретно заявил, что целью было «прочитать текстовый файл».
Простой
#include <fstream>
#include <iomanip>
ifstream ifs ("file");
ifs >> noskipws
вот и все.
Вы имели в виду "ifs >> noskipws >> some_string"?
std::ifstream ifs( "filename.txt" );
std::string str( ( std::istreambuf_iterator<char>( ifs ) ),
std::istreambuf_iterator<char>()
);
ifstream ifile(path);
std::string contents((std::istreambuf_iterator<char>(ifile)), std::istreambuf_iterator<char>());
ifile.close();
Еще один лучший способ - использовать istreambuf_iterator, а пример кода приведен ниже:
ifstream inputFile("test.data");
string fileData(istreambuf_iterator<char>(inputFile), istreambuf_iterator<char>());
Я также обнаружил, что метод получать() объекта ifstream также может читать все символы файла, для чего не требуется отключение std::ios_base::skipws. Цитата из Учебник по C++:
Several of the unformatted operations deal with a stream one byte at a time. These operations, which are described in Table 17.19, read rather ignore whitespaces.
Эти операции перечислены ниже: 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 - десятичное представление символа новой строки и пробела. Очевидно, все символы прочитаны.
Использование хорошо() лучше, чем eof (). Если требуется чтение символов по символам, если (myfile >> ch) - правильный путь, а проверка на eof - нет. См .: parashift.com/c++-faq-lite/input-output.html#faq-15.5