Odczyt całego pliku ASCII do C++ std:: string [duplikat]
Muszę wczytać cały plik do pamięci i umieścić go w C++ std::string
.
Gdybym miał to przeczytać do char[]
, odpowiedź byłaby bardzo prosta:
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 ...
Teraz chcę zrobić dokładnie to samo, ale używając std::string
zamiast char[]
. Chcę unikać pętli, tzn. ja Nie chcę:
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()
Jakieś pomysły? 9 answers
Update: okazuje się, że ta metoda, choć dobrze podąża za idiomami STL, jest w rzeczywistości zaskakująco nieefektywna! Nie rób tego z dużymi plikami. (Zobacz: http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html )
Możesz utworzyć z pliku iterator streambuf i zainicjalizować nim łańcuch znaków:
#include <string>
#include <fstream>
#include <streambuf>
std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
Nie wiem skąd bierzesz składnię t.open("file.txt", "r")
. Z tego, co wiem, to nie jest metoda, która std::ifstream
ma. Wygląda na to, że się pomyliłeś. z C fopen
.
Edit: zwróć również uwagę na dodatkowe nawiasy wokół pierwszego argumentu do konstruktora łańcuchowego. są niezbędne. Zapobiegają one problemowi znanemu jako " najbardziej irytujący parse", który w tym przypadku nie spowoduje błędu kompilacji, jak zwykle, ale da interesujące (Czytaj: złe) wyniki.
Podążając za punktem Keithba w komentarzach, oto sposób, aby to zrobić, który przydziela całą pamięć z przodu (zamiast w zależności od automatycznej realokacji klasy string):
#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>());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-23 19:31:27
Jest kilka możliwości. Ten, który lubię, używa stringstream jako pośrednika:
std::ifstream t("file.txt");
std::stringstream buffer;
buffer << t.rdbuf();
Teraz zawartość pliku.txt " są dostępne w postaci buffer.str()
.
Inna możliwość (choć na pewno mi się to nie podoba) jest o wiele bardziej podobna do Twojej oryginalnej:
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(&buffer[0], size);
Oficjalnie nie jest to wymagane do pracy w standardzie C++98 lub 03 (string nie jest wymagany do przechowywania danych w sposób ciągły), ale w rzeczywistości działa ze wszystkimi znanymi implementacjami, A C++11 i późniejsze wymagają ciągłego przechowywania, więc gwarantowana jest praca z nimi.
Co do tego, dlaczego nie lubię tego drugiego, jak również: po pierwsze, ponieważ jest dłuższy i trudniejszy do odczytania. Po drugie, ponieważ wymaga to inicjalizacji zawartości łańcucha z danymi, na których Ci nie zależy, a następnie natychmiastowego zapisania tych danych(TAK, Czas inicjalizacji jest zwykle trywialny w porównaniu do odczytu, więc prawdopodobnie nie ma to znaczenia, ale dla mnie nadal wydaje się to trochę złe). Po trzecie, w pliku tekstowym, pozycja X w plik nie musi oznaczać, że będziesz musiał czytać znaki X, aby osiągnąć ten punkt-nie jest wymagane, aby wziąć pod uwagę rzeczy, takie jak tłumaczenia końca linii. Na prawdziwych systemach, które wykonują takie tłumaczenia (np. Windows) przetłumaczona forma jest krótsza niż to, co jest w pliku (np. "\R\n" w pliku staje się "\n" w przetłumaczonym łańcuchu), więc wszystko, co zrobiłeś, jest zarezerwowane trochę dodatkowego miejsca, którego nigdy nie używasz. Ponownie, tak naprawdę nie powoduje większego problemu, ale i tak czuje się trochę źle.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-18 18:05:22
Myślę, że najlepszym sposobem jest użycie string stream. prosto i szybko !!!
#include <fstream>
#include <iostream>
#include <sstream> //std::stringstream
int main() {
std::ifstream inFile;
inFile.open("inFileName"); //open the input file
std::stringstream strStream;
strStream << inFile.rdbuf(); //read the file
std::string str = strStream.str(); //str holds the content of the file
std::cout << str << "\n"; //you can do anything with the string!!!
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-05 12:57:19
Może nie znajdziesz tego w żadnej książce lub stronie, ale dowiedziałem się, że działa całkiem dobrze:
ifstream ifs ("filename.txt");
string s;
getline (ifs, s, (char) ifs.eof());
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-25 12:30:55
Wypróbuj jedną z tych dwóch metod:
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
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-05 12:50:38
Wymyśliłem inny sposób, który działa z większością strumieni, w tym 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();
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-05 12:58:41
Jeśli zdarzy ci się użyć glibmm Możesz spróbować 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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-07 14:55:31
Mógłbym to zrobić tak:
void readfile(const std::string &filepath,std::string &buffer){
std::ifstream fin(filepath.c_str());
getline(fin, buffer, char(-1));
fin.close();
}
Jeśli jest to coś, na co warto się pochylić, proszę daj mi znać dlaczego
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-22 12:55:00
Myślę, że nie można tego zrobić bez jawnej lub niejawnej pętli, bez wczytania do tablicy znaków (lub innego kontenera) najpierw i ten konstruując łańcuch. Jeśli nie potrzebujesz innych możliwości ciągu znaków, można to zrobić za pomocą vector<char>
w ten sam sposób, w jaki obecnie używasz char *
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-08 17:30:26