Jak czytać wiersz po wierszu lub cały plik tekstowy naraz?

86

Jestem w tutorialu, który wprowadza pliki (jak czytać i zapisywać z \ do pliku)

Po pierwsze, to nie jest praca domowa, to tylko ogólna pomoc, której szukam.

Wiem, jak czytać po jednym wyrazie, ale nie wiem, jak czytać po jednym wierszu na raz ani jak czytać cały plik tekstowy.

Co jeśli mój plik zawiera 1000 słów? Czytanie każdego słowa jest niepraktyczne.

Mój plik tekstowy o nazwie (Odczyt) zawiera następujące elementy:

Uwielbiam grać w gry Uwielbiam czytać Mam 2 książki

Oto, co osiągnąłem do tej pory:

#include <iostream>
#include <fstream>

using namespace std;
int main (){

  ifstream inFile;
  inFile.open("Read.txt");

  inFile >>

Czy jest jakikolwiek sposób na odczytanie całego pliku na raz, zamiast czytać każdy wiersz lub każde słowo osobno?

Mody
źródło
4
Tutaj są dobrze zdefiniowane odpowiedzi: stackoverflow.com/questions/551082/c-read-lines-from-file
sampson-chen
możliwy duplikat Jak odczytać wiersz z pliku tekstowego w c / c ++?
Adrian McCarthy
Czytanie słowo po słowie jest tylko nieznacznie wolniejsze niż wiersz po wierszu. Jeśli naprawdę potrzebujesz słów, lepiej je czytać. Czytaj wiersze, jeśli masz do czynienia z danymi liniowymi, takimi jak plik CSV.
@Arkadiy, że jest niepoprawne. W przypadku pliku o rozmiarze 100 MB odczyt wiersz po wierszu z łatwością zajmie kilka sekund, podczas gdy odczyt bloku 4 KB w czasie o sekundy mniej niż sekunda.
Vallentin
@Vallentin: Biorąc pod uwagę, że wszystkie strumienie są buforowane, rzeczywisty odczyt dysku jest już wykonywany blok po bloku. Reszta to tylko manipulowanie danymi w pamięci.

Odpowiedzi:

161

Możesz użyć std::getline:

#include <fstream>
#include <string>

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

Zauważ również, że lepiej jest po prostu skonstruować strumień plików z nazwami plików w jego konstruktorze, zamiast jawnie otwierać (to samo dotyczy zamykania, po prostu pozwól destruktorowi wykonać pracę).

Dalszą dokumentację na temat std::string::getline()można przeczytać w CPP Reference .

Prawdopodobnie najłatwiejszym sposobem odczytania całego pliku tekstowego jest po prostu połączenie pobranych wierszy.

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');
}  
111111
źródło
9
Chociaż nie jest to oczywiste, while(getline(f, line)) { ...}naprawdę jest to zalecany sposób. Wyjaśniono to tutaj: gehrcke.de/2011/06/ ... --- tam również znajdziesz przydatne sposoby na prawidłową obsługę błędów.
Dr Jan-Philip Gehrcke
1
Powyższy kod nie skompiluje się bez#include <iostream>
Tyguy7
@ Tyguy7 Dlaczego miałoby #include <iostream>być wymagane? Wydaje mi się, że <fstream>i <string>wystarczy. Jeśli masz na myśli std::getline, to jest w <string>środku, a nie w <iostream>.
Fabio mówi Przywróć Monikę
@FabioTurati Nie jestem pewien, po prostu wiem, że kiedy to włączyłem, wszystko się skompilowało.
Tyguy7
19

Wiem, że to naprawdę bardzo stary wątek, ale chciałbym również wskazać inny sposób, który jest naprawdę bardzo prosty ... Oto przykładowy kod:

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

int main() {

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

    while(file >> content) {
        cout << content << ' ';
    }
    return 0;
}
user2673553
źródło
2
Dobra odpowiedź, użyłem tego ze stringstreamem zamiast cout, aby przenieść cały plik do gigantycznego stringstream
bjackfly
5

Myślę, że możesz użyć funkcji istream .read (). Możesz po prostu zapętlić fragment z rozsądnym rozmiarem i odczytać bezpośrednio do bufora pamięci, a następnie dołączyć go do jakiegoś dowolnego kontenera pamięci (takiego jak std :: vector). Mógłbym napisać przykład, ale wątpię, czy chcesz kompletnego rozwiązania; daj mi znać, jeśli będziesz potrzebować dodatkowych informacji.

Bartek Banachewicz
źródło
Nie wiem, kto zlekceważył tę odpowiedź, ale to dobrze, może nie jestem z twoich standardów, ale używam tego samego
Javasist
4

Cóż, aby to zrobić, można również użyć funkcji freopen dostarczonej w C ++ - http://www.cplusplus.com/reference/cstdio/freopen/ i czytać plik linia po linii w następujący sposób -:

#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;
}
AnkitSablok
źródło
1

Inną metodą, o której jeszcze nie wspomniano, jest std::vector.

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

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

Następnie możesz po prostu powtórzyć wektor i zmodyfikować / wyodrębnić to, czego potrzebujesz /

Bugster
źródło
4
To vectorniepotrzebny krok. Możesz iterować nad ifstreamusing std::istream_iterator<std::string>(inFile).
Joseph Mansfield,
0

możesz również użyć tego do odczytania wszystkich wierszy w pliku jeden po drugim, a następnie wydrukowania 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;
}

mam nadzieję, że to ci pomoże :)

Amirhosein Roshan
źródło
0

cześć stary, to jest sposób na odczytanie ciągu w dokładnym wierszu przy użyciu tego kodu

mam nadzieję, że to może ci pomóc!

#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;
}

Powodzenia !

Amirhosein Roshan
źródło