2008-09-25 25 views
8

Standart C++ dosyasındaki bir dosyadan bir dize almanın hızlı ve kolay bir yoluna ihtiyacım var. Kendi yazabilirim, ancak C++ 'da standart bir yol olup olmadığını bilmek istiyorum. Bunun EşdeğerC++ dosyasındaki bir dizgede okumak için tek liner var mı?

Eğer Kakao biliyorsanız:

NSString *string = [NSString stringWithContentsOfFile:file]; 

cevap

17

Bunu yapabiliriz ama uzun çizgi:

#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; 
} 

Düzenlendi: yerine "istream_iterator" nin "istreambuf_iterator"

+0

Sadece ',' işlecini kullandınız, aslında bir satırda aralarında noktalı virgül içeren bir sürü ifade koymak gibi. Ama bununla birlikte, benimki bir çizgiyi alttan geçirir, güzel. –

+0

Bir istreambuf_iterator kullanırsanız (bkz. Martin York'un gönderimime ilişkin yorumu) noskipws'ı unutabilirsiniz. –

+0

Başka bir yorum, ifstream geçicidir, buna rağmen yine de sizin için istream_iterators olurken kapanmayacağından emin misiniz? Bu değerlendirmeyi derleyici özel olurdu. –

3

standart C++ kütüphanesi bunu bir işlev sağlamaz.

+0

En iyi cevap. Elbette, yapılabilir, ama bu bir karmaşa. Bunu kabul etmek çok daha iyi değil ve kendi yaz. Tek bir işlev çağrısı kesinlikle bir tek liner olacaktır. –

2

En Yapabileceğim 5 satır:

#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

f.seekg() hilesi, dosyanın uzunluğuyla ilgili her zaman doğru mu? Windows'ta CRLF dönüşümü nedir? –

+0

Sanırım dosyayı ikili modda açabilirsin, bu yüzden sorun değil. –

10

bir istream_iterator ile neredeyse mümkün Its

#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)); 
} 

Düzenlendi - düz içine şimdi, ara dize akışının kopyalarını kurtuldum (3 çizgi!) dize ve şimdi whitespace göz ardı istreambuf_iterator, kullanarak (yorumunuz için Martin York teşekkürler).

+0

Bunu kendi işlevine koyun ve şimdi bir tane linkin var. Sadece bu fonksiyonu çağır. – Zooba

+0

Neden istreambuf_iterator () işlevini kullanmayın. Beyaz alanı atlamıyor. –

+0

@Martin York - teşekkürler, aslında bunun için arama yapmaya çalışıyordum, ama bunu düşünemedim. –

2

ne dersiniz:

#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; 
} 
0

sen gibi yaparsanız, dosyasında bir 0x1A byte endişelenmeden dosyasında okuyabilirsiniz aşağıdaki (ancak düzgün güzel aşağıda aksine sarılmış) (örneğin) kısa dosya okuma kesme. Önceden önerilen yöntemler bir dosyada bir 0x1A'yı (örneğin) tıkayacaktır.


#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); 
} 

Ancak, zaten uygulanan bir 1-liner değil.

Düzenleme: 0x1A, ios_base :: binary'nin bunu kapsayacağı gibi iyi bir örnek değildi. Bununla birlikte, daha sonra C++ akışları bile png dosyalarında bir kerede .read() ile okurken sıkıntı verir. C yolunu kullanmak daha iyi çalışır. Sadece nedenini göstermek için iyi bir örnek hatırlayamıyorum. Büyük olasılıkla .read() ile bir döngüsündeki bloklar halinde ikili bir dosya oluşturmak yerine C++ akışlarıyla ilgili bir problem olabilirdi. Yani, bu yazıyı dikkate almayın.

0
std::string temp, file; std::ifstream if(filename); while(getline(if, temp)) file += temp; 

Bu kısa ya da tek tablo satır değil kullanmak ama Bu bir çizgi ve gerçekten o kadar da kötü değil.

İlgili konular