Skaitykite visą ASCII failą C ++ std :: string

Turiu perskaityti visą failą atmintyje ir įdėti ją į C ++ std::string .

Jei perskaičiau jį char[] , atsakymas būtų labai paprastas:

 std::ifstream t; int length; t.open("file.txt"); // open input file t.seekg(0, std::ios::end); // go to the end length = t.tellg(); // report location (this is the length) t.seekg(0, std::ios::beg); // go back to the beginning buffer = new char[length]; // allocate memory for a buffer of appropriate dimension t.read(buffer, length); // read the whole file into the buffer t.close(); // close file handle // ... Do stuff with buffer here ... 

Dabar noriu padaryti tą patį, bet naudojant std::string vietoj char[] . Noriu išvengti ciklų, t.y. Nenoriu:

 std::ifstream t; t.open("file.txt"); std::string buffer; std::string line; while(t){ std::getline(t, line); // ... Append line to buffer and go on } t.close() 

Bet kokios idėjos?

497
08 апр. nustatytas „ Escualo“ 08 balandis. 2010-04-08 20:19 '10, 20:19, 2010-04-08 20:19
@ 9 atsakymai

Atnaujinti :. Pasirodo, kad šis metodas, gerai stebintis STL idiomas, iš tikrųjų yra netikėtai neveiksmingas! Nedarykite to su dideliais failais. (Žr. Http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html )

Streambuf galite kartoti iš failo ir su juo inicijuoti eilutę:

 #include <string> #include <fstream> #include <streambuf> std::ifstream t("file.txt"); std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); 

Nežinote, kur gausite t.open("file.txt", "r") sintaksę. Kiek aš žinau, tai nėra metodas, kuris turi std::ifstream . Panašu, kad jį fopen su C fopen .

Redaguoti: taip pat atkreipkite dėmesį į papildomus skliaustelius aplink pirmąjį eilutės konstruktoriaus argumentą. Tai svarbu. Jie užkerta kelią problemai, vadinamai „ gėdingiausiu analizavimu “, kuris šiuo atveju iš tikrųjų nesuteiks kompiliavimo klaidos, kaip paprastai būna, bet duos jums įdomius (skaitytus: neteisingus) rezultatus.

Po KeithB komentarų komentaruose, tai yra būdas tai padaryti, kuris paskirsto visą atmintį priešais (užuot pasikliaudamas automatiniu linijos perskirstymu):

 #include <string> #include <fstream> #include <streambuf> std::ifstream t("file.txt"); std::string str; t.seekg(0, std::ios::end); str.reserve(t.tellg()); t.seekg(0, std::ios::beg); str.assign((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>()); 
431
08 апр. Atsakymas, kurį pateikė Tyler McHenry Apr 08 2010-04-08 20:23 '10, 08:23 PM 2010-04-08 20:23

Yra keletas galimybių. Man patinka naudoti eilutės srautą kaip tarpinį:

 std::ifstream t("file.txt"); std::stringstream buffer; buffer << t.rdbuf(); 

Dabar buffer.str() „file.txt“ turinys pateikiamas eilutėje kaip buffer.str() .

Kita galimybė (nors man tai nepatinka) yra daug labiau panaši į jūsų originalą:

 std::ifstream t("file.txt"); t.seekg(0, std::ios::end); size_t size = t.tellg(); std::string buffer(size, ' '); t.seekg(0); t.read( size); 

Oficialiai tai nėra reikalinga C ++ 98 arba 03 (eilutės nereikia saugoti duomenims greta), tačiau iš tikrųjų jis veikia su visomis žinomomis diegimo priemonėmis, o C ++ 11 ir vėlesnėms versijoms reikia nuolatinio saugojimo, todėl garantuoja darbą su jais.

Dėl to, kodėl taip pat nemėgstu paskutinis dalykas: pirma, nes vis sunkiau skaityti. Antra, todėl, kad reikia inicijuoti eilutės turinį su duomenimis, kurių jums nereikia, tada iškart užrašykite šiuos duomenis (taip, iniciacijos laikas paprastai yra nereikšmingas, palyginti su skaitymu, todėl tikriausiai nesvarbu, tačiau Man vis dar atrodo neteisinga. Trečia, tekstinėje rinkmenoje X padėtis faile nebūtinai reiškia, kad jūs perskaitysite X simbolius, kad pasiektumėte šį tašką - jums nereikia atsižvelgti į tokius dalykus kaip vertimo žodžiu pabaigoje. Realiose sistemose, kuriose atliekami tokie vertimai (pvz., „Windows“), išversta forma yra trumpesnė už failą (t. Y. „R“ faile išverstoje eilutėje tampa „n“), todėl visi jūs rezervavote šiek tiek papildomos vietos, kurios niekada nenaudojate. Vėlgi, tai tikrai nesukelia rimtos problemos, bet bet kuriuo atveju atrodo šiek tiek neteisinga.

652
08 апр. Atsakymą pateikė Jerry Coffin balandžio 08 2010-04-08 20:53 '10, 20:53, 2010-04-08 20:53

Manau, geriausias būdas yra naudoti styginių srautą. lengva ir greita!

 ifstream inFile; inFile.open(inFileName);//open the input file stringstream strStream; strStream << inFile.rdbuf();//read the file string str = strStream.str();//str holds the content of the file cout << str << endl;//you can do anything with the string!!! 
47
12 нояб. Atsakymas pateikiamas mili . Lapkričio 12 d. 2013-11-12 09:08 '13, 9:08, 2013-11-12 09:08

Negalite jo rasti jokioje knygoje ar svetainėje, bet sužinojau, kad jis veikia labai gerai:

 ifstream ifs ("filename.txt"); string s; getline (ifs, s, (char) ifs.eof()); 
9
10 нояб. Atsakymą pateikė Ankit Acharya lapkričio 10 d. 2015-11-10 19:48 '15, 19:48, 2015-11-10 19:48

Išbandykite vieną iš šių dviejų būdų:

 string get_file_string(){ std::ifstream ifs("path_to_file"); return string((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); } string get_file_string2(){ ifstream inFile; inFile.open("path_to_file");//open the input file stringstream strStream; strStream << inFile.rdbuf();//read the file return strStream.str();//str holds the content of the file } 
5
05 февр. atsakymas pateikiamas Madx 05 Feb. 2015-02-05 15:50 '15 15:50 2015-02-05 15:50

Sužinojau kitą būdą, kuris veikia su daugeliu sostinių, įskaitant std :: cin!

 std::string readFile() { stringstream str; ifstream stream("Hello_World.txt"); if(stream.is_open()) { while(stream.peek() != EOF) { str << (char) stream.get(); } stream.close(); return str.str(); } } 
2
20 авг. atsakymas suteiktas yash101 20 rug . 2014-08-20 08:23 '14, 8:23 val. 2014-08-20 08:23

Galėčiau tai padaryti taip:

 void readfile(const std::string   std::ifstream fin(filepath.c_str()); getline(fin, buffer, char(-1)); fin.close(); } 

Jei taip galite nesutikti, pasakykite, kodėl

1
22 окт. atsakymas duotas chunkyguy 22 spalis 2012-10-22 15:55 '12, 15:55 pm 2012-10-22 15:55

Jei naudojate glibmm , galite pabandyti glib :: file_get_contents .

 #include <iostream> #include <glibmm.h> int main() { auto filename = "my-file.txt"; try { std::string contents = Glib::file_get_contents(filename); std::cout << "File data:\n" << contents << std::endl; catch (const Glib::FileError e) { std::cout << "Oops, an error occurred:\n" << e.what() << std::endl; } return 0; } 
1
07 авг. atsakymas, kurį pateikė Artem Vorotnikov 07 rug. 2016-08-07 17:55 '16 at 17:55 pm 2016-08-07 17:55

Nemanau, kad tai galite padaryti be aiškios ar netiesioginės kilpos, pirmiausia neperskaitę char masyvo (arba kito konteinerio) ir dešimt pastatę eilutę. Jei jums nereikia kitų styginių galimybių, tai galite padaryti naudodami vector<char> kaip šiuo metu naudojate char * .

-4
08 апр. KeithB atsakymas, pateiktas balandžio 8 d 2010-04-08 20:30 '10, 20:30, 2010-04-08 20:30