هل هناك سطر واحد يمكن قراءته في ملف إلى سلسلة في C++؟

StackOverflow https://stackoverflow.com/questions/136703

  •  02-07-2019
  •  | 
  •  

سؤال

أحتاج إلى طريقة سريعة وسهلة للحصول على سلسلة من ملف بلغة C++ القياسية.يمكنني أن أكتب طريقتي الخاصة، لكن أريد فقط معرفة ما إذا كانت هناك طريقة قياسية بالفعل في لغة C++.

ويعادل هذا إذا كنت تعرف الكاكاو:

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

لكن، نعم، إنها ليست خطًا واحدًا تم تنفيذه بالفعل.

يحرر:لم يكن 0x1A مثالًا جيدًا لأن ios_base::binary سيغطي ذلك.ومع ذلك، حتى في هذه الحالة، غالبًا ما تسبب لي تدفقات C++ مشكلة عند قراءة ملفات png مرة واحدة باستخدام .read().استخدام طريقة C يعمل بشكل أفضل.لا أستطيع تذكر مثال جيد لتوضيح السبب.ربما كان الأمر مع .read()ing ملف ثنائي في كتل في حلقة بدلاً من ذلك يمكن أن يكون مشكلة في تدفقات C++.لذلك، تجاهل هذا المنصب.

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

إنه ليس سطرًا قصيرًا أو عبارة واحدة، ولكنه سطر واحد وهو في الحقيقة ليس بهذا السوء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top