Как прочитать файл построчно или весь текстовый файл сразу?

Я в учебнике, который знакомит с файлами (как читать из файла и записывать в файл)

Прежде всего, это не домашнее задание, это просто общая помощь, которую я ищу.

Я знаю, как читать по одному слову за раз, но я не знаю, как читать по одной строке или как читать весь текстовый файл.

Что делать, если мой файл содержит 1000 слов? Читать весь файл слово за словом нецелесообразно.

Мой текстовый файл с именем Read содержит следующее:

I love to play games
I love reading
I have 2 books

Это то, что я сделал до сих пор:

#include <iostream>
#include <fstream>

using namespace std;
int main (){
   
  ifstream inFile;
  inFile.open("Read.txt");

  inFile >>

Есть ли способ прочитать весь файл сразу, вместо того, чтобы читать каждую строку или каждое слово отдельно?


person Mody    schedule 23.10.2012    source источник
comment
Здесь есть четко определенные ответы: stackoverflow.com/questions/551082/c-read-lines- из файла   -  person sampson-chen    schedule 23.10.2012
comment
возможный дубликат Как прочитать строку из текстовый файл в c/c++?   -  person Adrian McCarthy    schedule 23.10.2012
comment
Чтение слово за словом лишь незначительно медленнее, чем чтение строки за строкой. Если вам действительно нужны слова, то лучше читать слова. Читайте строки, если вы имеете дело со строковыми данными, такими как файл CSV.   -  person    schedule 23.10.2012
comment
@Аркадий, это неправильно. Для файла размером 100 МБ чтение строки за строкой легко займет секунды, а чтение блока размером 4 КиБ за секунды меньше секунды.   -  person vallentin    schedule 31.07.2016
comment
@Vallentin: Учитывая, что все потоки буферизованы, фактическое чтение диска уже выполняется поблочно. Остальное просто манипулирует данными в памяти.   -  person    schedule 01.08.2016
comment
@Arkadiy это смешно, потому что я действительно тестировал скорость вчера. От самого быстрого к самому медленному fread 4 KiB, fread 128 bytes, std::getline, fgetc, ifstream::get. Где fread заняло 0,15 секунды, а std::getline заняло 6 секунд для текстового файла размером 1 ГиБ.   -  person vallentin    schedule 01.08.2016
comment
@Vallentin - вы что-нибудь делали с прочитанными данными? Поскольку ОП в конечном итоге нужны слова, а не блоки, тест необходимо разбить на слова.   -  person    schedule 01.08.2016
comment
@Arkadiy ничего не делал с данными, кроме непрерывного чтения файла до конца. Мне нужно было что-то похожее на OP, и в итоге я сделал это через fread 4 KiB. Это работало, имея 2 блока одновременно. Таким образом, если слово (или, лучше сказать, последнее слово) превышало первый блок, оно продолжалось в следующем блоке. Так что да, если бы слово превышало 4 КиБ в длину, я бы не смог его прочитать. Но для меня это было не так, и я хотел ограничить любое копирование и перемещение памяти для сохранения скорости, и это сработало (в моем случае).   -  person vallentin    schedule 01.08.2016
comment
@Vallentin Если вам нужно начать с конца файла, вам лучше использовать поиск. И тогда, конечно, становится довольно сложно использовать стандартные потоки. Однако я не вижу ссылки на чтение до конца файла в сообщении ОП.   -  person    schedule 01.08.2016
comment
@Arkadiy Нет-нет, мне нужно было разделить каждое слово в файле пробелами. Дело в том, что если последний символ в буфере не является пробелом, то слово продолжается. Мы (очевидно) не можем сделать fread, потому что тогда мы не сможем получить первую часть слова. Таким образом, решение было 2 буфера. Опять же, я пытался НЕ копировать какую-либо память из буферов, что по сравнению с копированием каждого слова показало значительное улучшение скорости для файлов размером более 100 МБ.   -  person vallentin    schedule 01.08.2016
comment
@Vallentin Согласен, 2 буфера и копирование только пересекающихся слов было бы намного быстрее, но и гораздо сложнее для нового пользователя, чтобы получить правильно :) Если вы хотите ограничить себя словами, скопированными в std::string, то чтение слов скорее чем строки наверное не имеет значения.   -  person    schedule 01.08.2016


Ответы (9)


Вы можете использовать std::getline :

#include <fstream>
#include <string>

int main() 
{ 
    std::ifstream file("Read.txt");
    std::string str; 
    while (std::getline(file, str))
    {
        // Process str
    }
}

Также обратите внимание, что лучше просто создать файловый поток с именами файлов в его конструкторе, а не явно открывать (то же самое касается закрытия, просто позвольте деструктору выполнить работу).

Дополнительную документацию по std::string::getline() можно прочитать в Справочник по CPP.

Вероятно, самый простой способ прочитать весь текстовый файл — это просто соединить извлеченные строки.

std::ifstream file("Read.txt");
std::string str;
std::string file_contents;
while (std::getline(file, str))
{
  file_contents += str;
  file_contents.push_back('\n');
}  
person 111111    schedule 23.10.2012
comment
Хотя это и не очевидно, while(getline(f, line)) { ...} действительно является рекомендуемым способом сделать это. Это объясняется здесь: gehrcke.de/2011/06/ --- там вы также найдете полезные подходы для правильной обработки ошибок. - person Dr. Jan-Philip Gehrcke; 18.01.2015
comment
Приведенный выше код не будет компилироваться без #include <iostream> - person Tyguy7; 17.08.2015
comment
@ Tyguy7 Зачем нужен #include <iostream>? Мне кажется, что <fstream> и <string> достаточно. Если вы имеете в виду std::getline, то это <string>, а не <iostream>. - person Fabio says Reinstate Monica; 09.03.2017
comment
@FabioTurati Я не уверен, я просто знаю, что как только я его включил, все скомпилировалось нормально. - person Tyguy7; 16.05.2017

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

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    ifstream file("filename.txt");
    string content;

    while(file >> content) {
        cout << content << ' ';
    }
    return 0;
}
person user2673553    schedule 29.10.2013
comment
Хороший ответ, я использовал это со строковым потоком вместо cout, чтобы получить весь файл в гигантский строковый поток. - person bjackfly; 06.02.2014

Я думаю, вы могли бы использовать функцию istream .read(). Вы можете просто выполнить цикл с разумным размером фрагмента и прочитать его непосредственно в буфер памяти, а затем добавить его в какой-либо произвольный контейнер памяти (например, std::vector). Я мог бы написать пример, но сомневаюсь, что вам нужно полное решение; пожалуйста, дайте мне знать, если вам понадобится дополнительная информация.

person Bartek Banachewicz    schedule 23.10.2012
comment
Я не знаю, кто проголосовал за этот ответ, но это хорошо, может быть, я не по вашим стандартам, но я использую то же самое - person Javasist; 25.10.2012

Что ж, для этого также можно использовать функцию freopen, предусмотренную в C++ — http://www.cplusplus.com/reference/cstdio/freopen/ и прочитайте файл построчно следующим образом:

#include<cstdio>
#include<iostream>

using namespace std;

int main(){
   freopen("path to file", "rb", stdin);
   string line;
   while(getline(cin, line))
       cout << line << endl;
   return 0;
}
person AnkitSablok    schedule 30.04.2015

Еще один метод, который еще не упоминался, — это std::vector.

std::vector<std::string> line;

while(file >> mystr)
{
   line.push_back(mystr);
}

Затем вы можете просто перебрать вектор и изменить/извлечь то, что вам нужно/

person Bugster    schedule 23.10.2012
comment
vector — ненужный шаг. Вы можете перебрать ifstream, используя std::istream_iterator<std::string>(inFile). - person Joseph Mansfield; 23.10.2012

вы также можете использовать это, чтобы прочитать все строки в файле одну за другой, а затем напечатать i

#include <iostream>
#include <fstream>

using namespace std;



bool check_file_is_empty ( ifstream& file){
    return file.peek() == EOF ;
}

int main (){


    string text[256];
    int lineno ;
    ifstream file("text.txt");
    int num = 0;

    while (!check_file_is_empty(file))
    {    
        getline(file , text[num]);
        num++;
    }
    for (int i = 0; i < num ; i++)
    {
        cout << "\nthis is the text in " <<  "line " << i+1 << " :: " << text[i] << endl ;


    }
    
    system("pause");

    return 0;
}

надеюсь, это может помочь вам :)

person Amirhosein Roshan    schedule 01.11.2020

привет, братан, это способ прочитать строку в точной строке, используя этот код

надеюсь, что это может помочь вам!

#include <iostream>
#include <fstream>

using namespace std;


int main (){


    string text[1];
    int lineno ;
    ifstream file("text.txt");
    cout << "tell me which line of the file you want : " ;
    cin >> lineno ; 



    for (int i = 0; i < lineno ; i++)
    {
        
        getline(file , text[0]);

    }   

    cout << "\nthis is the text in which line you want befor  :: " << text[0] << endl ;
    system("pause");

    return 0;
}

Удачи !

person Amirhosein Roshan    schedule 01.11.2020

Приведенные выше решения великолепны, но есть лучшее решение для чтения файла сразу:

fstream f(filename);
stringstream iss;
iss << f.rdbuf();
string entireFile = iss.str();
person Chiang Cliff    schedule 18.06.2021

Приведенный ниже фрагмент поможет вам прочитать файлы, состоящие из символов Юникода.

CString plainText="";
errno_t errCode = _tfopen_s(&fStream, FileLoc, _T("r, ccs=UNICODE"));
    if (0 == errCode)
    {
        CStdioFile File(fStream);
        CString Line;
        while (File.ReadString(Line))
        {
            plainText += Line;
        }
    }
    fflush(fStream);
    fclose(fStream);

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

person Sarath Govind    schedule 18.06.2021
comment
Этот ответ не переносим из-за использования CString - person Michael Kotzjan; 18.06.2021
comment
чтобы использовать CString, просто включите файл заголовка atlstr.h #include‹atlstr.h› - person Sarath Govind; 22.06.2021