Используя fstream для чтения каждого символа, включая пробелы и новую строку
Я хотел использовать fstream
для чтения txt файла.
Я использую inFile >> characterToConvert
, но проблема в том, что это опускает любые пробелы и новую строку.
Я пишу программу шифрования, поэтому мне нужно включить пробелы и новые строки.
Каким будет правильный способ сделать это?
Ответы
Ответ 1
Вероятно, лучший способ - прочитать содержимое всего файла в строку, что можно сделать очень легко, используя ifstream rdbuf()
метод
std::ifstream in("myfile");
std::stringstream buffer;
buffer << in.rdbuf();
std::string contents(buffer.str());
Теперь вы можете использовать регулярные манипуляции с строками, теперь у вас есть все, что есть в файле.
В то время как Tomek спрашивал о чтении текстового файла, тот же подход будет работать для чтения двоичных данных, хотя для двоичного флага std:: ios:: для предоставления при создании потока входных файлов.
Ответ 2
Для шифрования вам лучше открыть файл в двоичном режиме. Используйте что-то вроде этого, чтобы поместить байты файла в вектор:
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);
Изменить: исправлена тонкая ошибка в соответствии с комментариями.
Ответ 3
Я не тестировал это, но считаю, что вам нужно очистить флаг пропущенных пробелов:
inFile.unsetf(ios_base::skipws);
Я использую следующую ссылку для потоков С++:
Библиотека IOstream
Ответ 4
Следующий код С++ прочитает весь файл...
#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;
}
разместите свой код, и я могу дать вам более конкретную помощь в вашей проблеме...
Ответ 5
Много преимуществ слоя istream обеспечивает базовое форматирование и синтаксический анализ для простых типов ro и потока. Для целей, которые вы описываете, ничто из этого не имеет особого значения, и вас просто интересует файл как поток байтов.
Для этой цели вам может быть лучше использовать интерфейс 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" вперед, а затем возвращает текущий char), sgetc (получает текущий char, но не перемещает указатель "get" ) и sungetc (если возможно, резервное копирование указателя "get" на одну позицию).
Если вам не нужны какие-либо операторы вставки и извлечения, предоставляемые классом istream, и просто нужен базовый байтовый интерфейс, часто интерфейс streambuf (filebuf, stringbuf) более уместен, чем интерфейс istream (ifstream, istringstream).
Ответ 6
Вы можете вызвать int fstream::get()
, который будет читать один символ из потока. Вы также можете использовать istream& fstream::read(char*, streamsize)
, который выполняет ту же операцию, что и get()
, только через несколько символов. Данные ссылки включают примеры использования каждого метода.
Я также рекомендую чтение и запись в двоичном режиме. Это позволяет правильному считыванию символов ASCII и их записи в файлы. В противном случае пара операций шифрования/дешифрования может привести к не идентичным файлам. Для этого вы открываете поток с отметкой ios::binary
. С двоичным файлом вы хотите использовать метод read()
.
Ответ 7
std::ifstream ifs( "filename.txt" );
std::string str( ( std::istreambuf_iterator<char>( ifs ) ),
std::istreambuf_iterator<char>()
);
Ответ 8
Для шифрования вы, вероятно, должны использовать read(). Алгоритмы шифрования обычно имеют дело с блоками фиксированного размера. О, и для открытия в двоичном режиме (без перевода frmo\n\r в \n), передайте ios_base:: двоичный код в качестве второго параметра для вызова constructor или open().
Ответ 9
Еще один лучший способ - использовать istreambuf_iterator, а пример кода выглядит следующим образом:
ifstream inputFile("test.data");
string fileData(istreambuf_iterator<char>(inputFile), istreambuf_iterator<char>());
Ответ 10
Простой
#include <fstream>
#include <iomanip>
ifstream ifs ("file");
ifs >> noskipws
что все.
Ответ 11
ifstream ifile(path);
std::string contents((std::istreambuf_iterator<char>(ifile)), std::istreambuf_iterator<char>());
ifile.close();
Ответ 12
Я также обнаружил, что метод get() объекта ifstream также может читать все символы файла, которые не требуют отмены std::ios_base::skipws
. Цитата из С++ 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 - десятичное представление символа новой строки и пробела. Очевидно, что все символы были прочитаны.
Ответ 13
Как правильно заметил Чарльз Бейли, вам не нужны службы fstream, чтобы читать байты. Так что забудьте об этом iostream глупости, используйте fopen/fread и сделайте с ним. C stdio является частью С++, вы знаете;)