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

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

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

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

Как правильно это сделать?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
32
0
74 030
13

Ответы 13

Следующий код на 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;
}

опубликуйте свой код, и я могу дать вам более конкретную помощь по вашей проблеме ...

Использование хорошо() лучше, чем eof (). Если требуется чтение символов по символам, если (myfile >> ch) - правильный путь, а проверка на eof - нет. См .: parashift.com/c++-faq-lite/input-output.html#faq-15.5

legends2k 21.09.2011 18:44

Для шифрования лучше открывать файл в двоичном режиме. Используйте что-то вроде этого, чтобы поместить байты файла в вектор:

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).

Alex B 30.09.2008 17:42

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

inFile.unsetf(ios_base::skipws);

Я использую следующую ссылку для потоков C++: Библиотека IOstream

да, обязательно нужно добавить это, если вы хотите читать двоичные данные, так как по умолчанию он включен.

js. 19.11.2010 19:21

Мне тоже нужен этот Кроме того для флага ios :: binary

jtooker 29.06.2017 22:01

Для шифрования вам, вероятно, следует использовать читать(). Алгоритмы шифрования обычно работают с блоками фиксированного размера. О, и чтобы открыться в двоичном режиме (без преобразования из \ 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.

Как я могу проголосовать за это больше? Это сэкономило бы мне ЧАСЫ программирования ... Вы были бы потрясены количеством советов Плохо (даже опытных пользователей стека), которые существуют на этом сайте.

Dylan_Larkin 05.12.2016 23:18

Большим преимуществом уровня 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 <>

Martin York 23.09.2008 02:34

Я согласен, но OP конкретно заявил, что целью было «прочитать текстовый файл».

Constantin 24.09.2008 02:35

Простой

#include <fstream>
#include <iomanip>


ifstream ifs ("file");
ifs >> noskipws

вот и все.

Вы имели в виду "ifs >> noskipws >> some_string"?

Vanuan 29.04.2011 15:52

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 - десятичное представление символа новой строки и пробела. Очевидно, все символы прочитаны.

Другие вопросы по теме