C++ STL Посимвольное считывание многострочного текстового файла в вектор строк

Некоторые новички, изучающие программирование, включающее STL, могут столкнуться с небольшой проблемой считывания текстового файла без потери форматирования. Это тот случай, когда необходимо считать файл со всеми переносами строк. Например, нужно считать данные в вектор строк, чтобы каждый элемент вектора был одним абзацем (текстом до переноса строки). Это может пригодиться, например, для красивого оформления решения задачки. Ведь если убить переносы строк в многострочном документе, то текст потеряет привычную привлекательность и будет какая-то не прикольная фигня (справедливости ради фигня эта чаще в Windows). С какой это целью и кому нужно, я без понятия, но может найдутся нуждающиеся новички, которым это или потребовалось или просто интересно как прием работы с текстовым файлом.

Нужно знать

Я приведу пример С++ для посимвольного считывания текста из многострочного тестового файла, с запоминанием каждого абзаца внутри вектора. Код проверен в MinGW

Такой вот пример задачки: "Как считать многострочный текстовый файл в вектор строк" Так как могут быть совсем еще только начавшие учить программирование С++, то разберемся подробно, что получается.

Я открываю файл, который расположен по указанному мною пути для чтения с форматированием (Есть еще бинарное чтение). Чтение с форматированием подходит для текстовых файлов, да и начинающим поначалу использовать этот способ проще. После открытия текстового файла для чтения, я начинаю посимвольно считывать из него символы в файловый поток in

Объект cin — это тоже потоковый объект. Ведь из определения

  • cin– объект класса ostream, соответствующий стандартному вводу. В общем случае он позволяет вводить данные c клавиатуры;

Объект cin = поток
Объект in = поток
То поток и это поток. Так и работать с ними можно одинаково. Вся разница только, что один поток принимает данные с клавиатуры, второй поток с файла. Имя потока в примере in, но вы можете задавать любое удобное (по правилам объявления переменных). Ведь это и поток и переменная одновременно. В скобках прописана константа, обозначающая путь к файлу (FName).
EOF — это символ конца файла. В каждом файле такой символ есть, вот после записи данных в ch, я сразу проверяю этот ch на то, что он НЕ является концом файла. Ведь если он не является, то надо читать символы дальше.

это получается как

Так мы добрались до внутри цикла. Внутри идет сборка строки, проверка ch на то, что он не является символом переноса строки и, если он является переносом, то собранная строка записывается в вектор. После записи строки s в вектор, строка обязательно очищается. Ведь если не очистить строку, то эта строка продолжит собираться с уже накопленными в ней символами. Ну и после выполнения цикла дописывается последняя строка в вектор строк.

Надеюсь написал настолько подробно, что вопросов будет меньше чем могло бы быть.
 
 
Какую ошибку обычно делают. Часто делают такую ошибку, что проверяют признак конца файла методом потока

В этом случае последний символ считывается дважды и можно словить выход за пределы массива при работе с вектором(массивом). Получается такая картина. метод get распознал в символе конец файла и не сдвинул in дальше, а последний символ считывается вдогонку. Так как in не сдвинулся, а догонка прошла, последний символ считается 2 раза. Пример же вообще сработать не должен.

Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

10 комментариев: C++ STL Посимвольное считывание многострочного текстового файла в вектор строк

  • Игорь говорит:

    Можно гораздо проще и изящней!

    http://www.cyberforum.ru/cpp-beginners/thread641025.html – источник

    Автор сайта отвечает:
    так-то можно, только это тут не вектор строк и тема изначально названа как посимвольное считывание.

  • Юлия говорит:

    Скажите пожалуйста, как можно  записать подстроку вектора в переменную?

    Я нашла такой метод: v.at(1).substr(1, 1); где  v- это вектор типа char(все как в вашей программе), я хочу считать первый символ второй строки в переменную, можно ли это как то реализовать?

    Автор сайта отвечает:
    Считать первый символ:

  • Максим говорит:

    ПОдскажите пожалуйста, а как выводить по 10, 20 или 30 строк на экран???

    • admin говорит:

      Построчно читать. Завести счетчик. На каждой итерации увеличивать счетчик. Цикл выполнять пока счетчик не достигнет нужного числа или файл не закончится.

  • Иван говорит:

    Ваша программа не будет работать, если в файле будут русские буквы. Если не изменять кодировку ввода-вывода, то русские буквы будут кодироваться отрицательными числами. Среди них есть такая буковка «я», у которой код -1. К справке EOF это тоже -1. Так что на первой букве «я» все остановится.
    P.S. Да, я знаю, что год прошел. Просто у меня немножечко подгорает.

    • admin говорит:

      Вы можете предложить решение?
      Чтобы буквы не получали значение меньше нуля, нужно использовать unsigned char.
      А вот, чтобы с кодировками проблему решить — это вопрос неприятный.

  • В говорит:

    Скажите пожалуйста, а как мне реализовать чтение нескольких символов. Я читаю файл формата JPEG и сохраняю его в TEMP.txt. Но я тут подумал и решил, что мне нужен массив строк, так как файл хранит шеснадцатиричную «ffd8 ffe0 0010 4a46» информацию по четыре символа  в четыре пары на строку. Так вот как мне считать все эти пары в двумерный массив строк. Я конечно понял как решить из выше описанного, но думаю это будет пахнуть говнокодом. Может вы предложите какой действующий вариант решения. Можно как-то читать по четыре символа? И я не против юзать векторы. Мне в дальнейшем как раз с матрицами векторов работать.

     

    P.S. Хоть пост и древний, но надеюсь вы ответите мне. Заранее спасибо.

  • Владимир говорит:

    А как считать несколько символов до пробела и поместить в массив. Вот что я хотел бы сделать на примере абстрактного кода:

     

    <php>

    string msg = «FFDD C05D BBFF 0000 C409 1111 1010 1100»;

    string str[5][7] = {

    {«FFDD», »C05D»,  ….. ….. …..  },

    { другая строка файла },

    }

     

    </php>

     

    Тобиш я хочу знать сколько в файле строк и сколько в каждой строке таких пар по 4 символа, а затем их поместить в массив строк с помощью цикла. Как реализовать подобное зарание спасибо.

    • admin говорит:

      Я покажу в течение недели. Я сейчас немного занят, устаю.
      Я покажу то, что Вы показываете, но не особо уверен, что это то, что Вам нужно.
      Если сроки поджимают, то лучше просить не меня. Меня надо немного подождать.

  • admin говорит:

Добавить комментарий

Ваш e-mail не будет опубликован.

Поиск

 
     
Яндекс.Метрика

НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Программист на ночь ставит два стакана. Один - с водой, другой - без воды. Первый - на случай, если захочет пить, Второй - если не захочет.

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок