Есть ли однострочная строка в файле для чтения в C ++? - PullRequest
8 голосов
/ 26 сентября 2008

Мне нужен быстрый простой способ получить строку из файла в стандартном C ++. Я могу написать свой, но просто хочу знать, есть ли уже стандартный способ, в C ++.

Эквивалент этого, если вы знаете Какао:

NSString *string = [NSString stringWithContentsOfFile:file];

Ответы [ 7 ]

17 голосов
/ 26 сентября 2008

Мы можем сделать это, но это длинная строка:

#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»

10 голосов
/ 26 сентября 2008

Это почти возможно с 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, который игнорирует пробелы (спасибо Martin York за ваш комментарий).

3 голосов
/ 26 сентября 2008

Стандартная библиотека C ++ не предоставляет функции для этого.

2 голосов
/ 26 сентября 2008

Как насчет:

#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;
}
2 голосов
/ 26 сентября 2008

Лучшее, что я могу сделать, это 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());
0 голосов
/ 30 августа 2010
std::string temp, file; std::ifstream if(filename); while(getline(if, temp)) file += temp;

Это не короткая строка или строка с одним утверждением, но это одна строка, и это действительно не так уж плохо.

0 голосов
/ 26 сентября 2008

Если вы сделаете это следующим образом (но правильно обернуты в отличии от приведенного ниже), вы можете прочитать файл, не беспокоясь о байте 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 работает лучше. Просто не могу вспомнить хороший пример, чтобы показать почему. Вероятно, именно с .read () бинарный файл в блоках в цикле может быть проблемой с потоками C ++. Итак, не обращайте внимания на этот пост.

...