Есть ли однострочник для чтения из файла в строку в C ++?
-
02-07-2019 - |
Вопрос
Мне нужен быстрый и простой способ получить строку из файла на стандартном C ++.Я могу написать свой собственный, но просто хочу знать, существует ли уже стандартный способ на C ++.
Эквивалент этого, если вы знаете Cocoa:
NSString *string = [NSString stringWithContentsOfFile:file];
Решение
Мы можем это сделать, но это длинная очередь :
#include<fstream>
#include<iostream>
#include<iterator>
#include<string>
using namespace std;
int main()
{
// The one-liner
string fileContents(istreambuf_iterator<char>(ifstream("filename.txt")), istreambuf_iterator<char>());
// Check result
cout << fileContents;
}
Отредактированный :используйте "istreambuf_iterator" вместо "istream_iterator".
Другие советы
Это почти возможно с istream_iterator (3 строки!)
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>
#include <sstream>
using namespace std;
int main()
{
ifstream file("filename.txt");
string fileContents;
copy(istreambuf_iterator<char>(file),
istreambuf_iterator<char>(),
back_inserter(fileContents));
}
Отредактировано - избавился от промежуточного потока строк, теперь копирует прямо в строку и теперь использует istreambuf_iterator, который игнорирует пробелы (спасибо Мартину Йорку за ваш комментарий).
Стандартная библиотека C ++ не предоставляет функции для этого.
Лучшее, что я могу сделать, это 5 строк:
#include <fstream>
#include <vector>
using namespace std;
ifstream f("filename.txt");
f.seekg(0, ios::end);
vector<char> buffer(f.tellg());
f.seekg(0, ios::beg);
f.read(&buffer[0], buffer.size());
Как насчет:
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
int main( void )
{
stringstream os(stringstream::out);
os << ifstream("filename.txt").rdbuf();
string s(os.str());
cout << s << endl;
}
Если вы сделаете это следующим образом (но должным образом завернете, в отличие от приведенного ниже), вы сможете читать в файле, не беспокоясь о том, что байт размером 0x1A в файле (например) сократит чтение файла.Ранее предложенные методы ограничат доступ к 0x1A (например) в файле.
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstdlib>
using namespace std;
int main() {
FILE* in = fopen("filename.txt", "rb");
if (in == NULL) {
return EXIT_FAILURE;
}
if (fseek(in, 0, SEEK_END) != 0) {
fclose(in);
return EXIT_FAILURE;
}
const long filesize = ftell(in);
if (filesize == -1) {
fclose(in);
return EXIT_FAILURE;
}
vector<unsigned char> buffer(filesize);
if (fseek(in, 0, SEEK_SET) != 0 || fread(&buffer[0], sizeof(buffer[0]), buffer.size(), in) != buffer.size() || ferror(in) != 0) {
fclose(in);
return EXIT_FAILURE;
}
fclose(in);
}
Но, да, это все же не уже реализованный 1-лайнер.
Редактировать:0x1A не был хорошим примером, поскольку ios_base::binary будет охватывать это.Однако даже тогда потоки C ++ часто доставляют мне проблемы при чтении в png-файлах всех сразу с помощью .read().Использование способа C работает лучше.Просто не могу вспомнить хороший пример, чтобы показать, почему.Вероятно, проблема с потоками C ++ заключалась в том, что .read() обрабатывал двоичный файл блоками в цикле, что может быть проблемой с потоками C ++.Итак, не обращайте внимания на этот пост.
std::string temp, file; std::ifstream if(filename); while(getline(if, temp)) file += temp;
Это не короткая строка с одним оператором, но это одна строка, и она действительно не так уж плоха.