Qual é a maneira mais elegante de ler um arquivo de texto com c ++?

Eu gostaria de ler todo o conteúdo de um arquivo de texto para um object std::string com c + +.

Com o Python, posso escrever:

 text = open("text.txt", "rt").read() 

É muito simples e elegante. Eu odeio coisas feias, então eu gostaria de saber – qual é a maneira mais elegante de ler um arquivo de texto com C ++? Obrigado.

Há muitas maneiras, você escolhe qual é o mais elegante para você.

Lendo para char *:

 ifstream file ("file.txt", ios::in|ios::binary|ios::ate); if (file.is_open()) { file.seekg(0, ios::end); size = file.tellg(); char *contents = new char [size]; file.seekg (0, ios::beg); file.read (contents, size); file.close(); //... do something with it delete [] contents; } 

Em std :: string:

 std::ifstream in("file.txt"); std::string contents((std::istreambuf_iterator(in)), std::istreambuf_iterator()); 

Em vetor :

 std::ifstream in("file.txt"); std::vector contents((std::istreambuf_iterator(in)), std::istreambuf_iterator()); 

Em string, usando stringsstream:

 std::ifstream in("file.txt"); std::stringstream buffer; buffer << in.rdbuf(); std::string contents(buffer.str()); 

file.txt é apenas um exemplo, tudo funciona bem para arquivos binários também, apenas certifique-se de usar ios :: binary no construtor ifstream.

Há outro tópico sobre esse assunto.

Minhas soluções deste segmento (ambas de uma linha):

O legal (veja a segunda solução de Milão):

 string str((istreambuf_iterator(ifs)), istreambuf_iterator()); 

e o jejum:

 string str(static_cast(stringstream() << ifs.rdbuf()).str()); 

Você parece falar de elegância como uma propriedade definida de “pequeno código”. Isso é, obviamente, subjetivo em certa medida. Alguns diriam que omitir toda a manipulação de erros não é muito elegante. Alguns diriam que o código claro e compacto que você entende imediatamente é elegante.

Escreva sua própria function / método de uma linha que lê o conteúdo do arquivo, mas torne-o rigoroso e seguro sob a superfície e você terá coberto ambos os aspectos da elegância.

Muito bem sucedida

/ Robert

Mas cuidado, pois uma string c ++ (ou mais concreta: uma string STL) é tão pequena quanto um C-String capaz de manter uma string de comprimento arbitrário – claro que não!

Dê uma olhada no membro max_size (), que fornece o número máximo de caracteres que uma string pode conter. Este é um número definido de implementação e pode não ser portável entre diferentes plataformas. O Visual Studio dá um valor de cerca de 4gigs para strings, outros podem dar apenas 64k e em 64Bit-platform ele pode te dar algo realmente grande! Depende e, claro, normalmente você vai correr em uma exceção bad_alloc devido ao esgotamento de memory muito tempo antes de atingir o limite de 4gig …

BTW: max_size () também é membro de outros contêineres STL! Ele fornecerá o número máximo de elementos de um determinado tipo (para o qual você instanciou o contêiner) que esse contêiner (teoricamente) poderá conter.

Então, se você está lendo um arquivo de origem desconhecida, você deve:
– Verifique seu tamanho e verifique se ele é menor que max_size ()
– Captura e processa as exceções de bad_alloc

E outro ponto: Por que você está interessado em ler o arquivo em uma string? Eu esperaria processá-lo ainda mais analisando-o de forma incremental ou algo assim, certo? Então, ao invés de lê-lo em uma string, você pode também lê-lo em uma stringstream (que basicamente é apenas um pouco de açúcar sintático para uma string) e fazer o processamento. Mas então você poderia fazer o processamento diretamente do arquivo também. Porque, se programado adequadamente, o stringstream poderia ser facilmente substituído por um stream de arquivos, ou seja, pelo próprio arquivo. Ou por qualquer outro stream de input, todos eles compartilham os mesmos membros e operadores e podem, assim, ser perfeitamente intercambiados!

E para o processamento em si: Também há muito que você pode ter automatizado pelo compilador! Por exemplo. digamos que você queira tokenizar a string. Ao definir um modelo adequado, as seguintes ações:
– Leitura de um arquivo (ou uma string ou qualquer outro stream de input)
– Como otimizar o conteúdo
– empurrando todos os tokens encontrados para um container STL
– ordena os tokens alfabeticamente
– elimina quaisquer valores duplos
pode tudo (!!) ser obtido em uma única (!) linha de C ++ – código (deixe de lado o modelo em si eo tratamento de erros)! É apenas uma única chamada da function std :: copy ()! Apenas google para “iterador token” e você terá uma idéia do que quero dizer. Então, isso parece-me ainda mais “elegante” do que apenas ler um arquivo …

Eu gosto do char * do Milan, mas com o std :: string.

 #include  #include  #include  #include  using namespace std; string& getfile(const string& filename, string& buffer) { ifstream in(filename.c_str(), ios_base::binary | ios_base::ate); in.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit); buffer.resize(in.tellg()); in.seekg(0, ios_base::beg); in.read(&buffer[0], buffer.size()); return buffer; } int main(int argc, char* argv[]) { if (argc != 2) { cerr << "Usage: this_executable file_to_read\n"; return EXIT_FAILURE; } string buffer; cout << getfile(argv[1], buffer).size() << "\n"; } 

(com ou sem o ios_base :: binary, dependendo se você quer newlines tranlated ou não. Você também pode alterar getfile para apenas retornar uma string para que você não tenha que passar uma string de buffer para dentro. Então, teste para ver se o compilador otimiza a cópia ao retornar.)

No entanto, isso pode parecer um pouco melhor (e ser muito mais lento):

 #include  #include  #include  #include  using namespace std; string getfile(const string& filename) { ifstream in(filename.c_str(), ios_base::binary); in.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit); return string(istreambuf_iterator(in), istreambuf_iterator()); } int main(int argc, char* argv[]) { if (argc != 2) { cerr << "Usage: this_executable file_to_read\n"; return EXIT_FAILURE; } cout << getfile(argv[1]).size() << "\n"; }