سؤال

وأريد أن أقرأ بايت غير موقعة من ملف ثنائي. لذلك كتبت التعليمة البرمجية التالية.

#include <iostream>
#include <fstream>
#include <vector>
#include <istream>

std::string filename("file");
size_t bytesAvailable = 128;
size_t toRead = 128;

std::basic_ifstream<unsigned char> inf(filename.c_str(), std::ios_base::in | std::ios_base::binary) ;
if (inF.good())
{
    std::vector<unsigned char> mDataBuffer;
    mDataBuffer.resize(bytesAvailable) ;
    inF.read(&mDataBuffer[0], toRead) ;
    size_t counted = inF.gcount() ;
}

وهذا يؤدي إلى القراءة في دائما 0 بايت كما هو مبين من قبل متغير فرزها.

ويبدو أن هناك إشارات على شبكة الإنترنت قائلا أنني بحاجة إلى تعيين الإعدادات المحلية لجعل هذا العمل. كيفية القيام بذلك بالضبط غير واضحة بالنسبة لي.

وهذا نفس رمز يعمل باستخدام نوع البيانات "شار" بدلا من "الحرف غير الموقعة '

ورمز أعلاه باستخدام الحرف غير الموقعة يبدو للعمل على ويندوز ولكن فشل تشغيل في colinux فيدورا 2.6.22.18.

وماذا أحتاج إلى القيام به للحصول على العمل لينكس؟

هل كانت مفيدة؟

المحلول

وC ++ لا تتطلب تنفيذ فقط لتوفير تخصصات واضحة لنسختين من الصفات الشخصية:

std::char_traits<char>
std::char_traits<wchar_t>

وتيارات وسلاسل تستخدم تلك الصفات لمعرفة مجموعة متنوعة من الأشياء، مثل قيمة EOF، مقارنة مجموعة من الشخصيات، واتساع ذات الطابع إلى int، وأشياء من هذا القبيل.

إذا مثيل تيار مثل

std::basic_ifstream<unsigned char>

لديك للتأكد من أن هناك المقابل تخصص شخصية سمة أن تيار يمكن استخدام وأن هذا التخصص لا تفعل أشياء مفيدة. وبالإضافة إلى ذلك، والجداول استخدام الأوجه للقيام التنسيق الفعلي وقراءة الأرقام. وبالمثل لديك لتوفير التخصصات تلك يدويا أيضا. المعيار لا يتطلب حتى تنفيذ لتعريف كامل من القالب الأساسي. لذلك يمكن أن aswell الحصول على خطأ الترجمة:

<اقتباس فقرة>   

خطأ: لا يمكن إنشاء مثيل تخصص الأمراض المنقولة جنسيا :: char_traits

وأود أن استخدام ifstream بدلا من ذلك (وهو basic_ifstream<char>) ثم يذهب ويقرأ في vector<char>. عند تفسير البيانات في الناقل، لا يزال بإمكانك تحويلها إلى unsigned char في وقت لاحق.

نصائح أخرى

لا تستخدم basic_ifstream لأنه يتطلب specializtion.

وعن طريق منطقة عازلة ثابت:

linux ~ $ cat test_read.cpp
#include <fstream>
#include <iostream>
#include <vector>
#include <string>


using namespace std;

int main( void )
{
        string filename("file");
        size_t bytesAvailable = 128;

        ifstream inf( filename.c_str() );
        if( inf )
        {
                unsigned char mDataBuffer[ bytesAvailable ];
                inf.read( (char*)( &mDataBuffer[0] ), bytesAvailable ) ;
                size_t counted = inf.gcount();
                cout << counted << endl;
        }

        return 0;
}
linux ~ $ g++ test_read.cpp
linux ~ $ echo "123456" > file
linux ~ $ ./a.out
7

وباستخدام ناقلات:

linux ~ $ cat test_read.cpp

#include <fstream>
#include <iostream>
#include <vector>
#include <string>


using namespace std;

int main( void )
{
        string filename("file");
        size_t bytesAvailable = 128;
        size_t toRead = 128;

        ifstream inf( filename.c_str() );
        if( inf )
        {

                vector<unsigned char> mDataBuffer;
                mDataBuffer.resize( bytesAvailable ) ;

                inf.read( (char*)( &mDataBuffer[0]), toRead ) ;
                size_t counted = inf.gcount();
                cout << counted << " size=" << mDataBuffer.size() << endl;
                mDataBuffer.resize( counted ) ;
                cout << counted << " size=" << mDataBuffer.size() << endl;

        }

        return 0;
}
linux ~ $ g++ test_read.cpp -Wall -o test_read
linux ~ $ ./test_read
7 size=128
7 size=7

وباستخدام الاحتياطي بدلا من تغيير الحجم في المكالمة الأولى:

linux ~ $ cat test_read.cpp

#include <fstream>
#include <iostream>
#include <vector>
#include <string>


using namespace std;

int main( void )
{
        string filename("file");
        size_t bytesAvailable = 128;
        size_t toRead = 128;

        ifstream inf( filename.c_str() );
        if( inf )
        {

                vector<unsigned char> mDataBuffer;
                mDataBuffer.reserve( bytesAvailable ) ;

                inf.read( (char*)( &mDataBuffer[0]), toRead ) ;
                size_t counted = inf.gcount();
                cout << counted << " size=" << mDataBuffer.size() << endl;
                mDataBuffer.resize( counted ) ;
                cout << counted << " size=" << mDataBuffer.size() << endl;

        }

        return 0;
}
linux ~ $ g++ test_read.cpp -Wall -o test_read
linux ~ $ ./test_read
7 size=0
7 size=7

وكما ترون، دون الدعوة إلى .resize (عد)، فإن حجم ناقلات تكون خاطئة. يرجى أن نضع ذلك في الاعتبار. وهو شائع الاستخدام الصب نرى cppReference

وهناك طريقة أسهل بكثير:

#include <fstream>
#include <vector>

using namespace std;


int main()
{
    vector<unsigned char> bytes;
    ifstream file1("main1.cpp", ios_base::in | ios_base::binary);
    unsigned char ch = file1.get();
    while (file1.good())
    {
        bytes.push_back(ch);
        ch = file1.get();
    }
    size_t size = bytes.size();
    return 0;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top