Подтвердить что ты не робот

Используя fstream для чтения каждого символа, включая пробелы и новую строку

Я хотел использовать fstream для чтения txt файла.

Я использую inFile >> characterToConvert, но проблема в том, что это опускает любые пробелы и новую строку.

Я пишу программу шифрования, поэтому мне нужно включить пробелы и новые строки.

Каким будет правильный способ сделать это?

4b9b3361

Ответ 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 является частью С++, вы знаете;)