2016-01-12 12 views
8

Tôi phải nhóm 5 unsigned char vectơ (data_length=5). Vào cuối nhóm, tôi muốn thêm một nhóm ID và viết chúng (nhóm dữ liệu + ID của nó) để tập tin. Trong đó các loại ID nhóm integer. Tôi làm nhiệm vụ đó như mã dưới đây. Nó có đúng không? Hình dưới đây cho thấy những gì tôi đang tham giaLàm thế nào tôi có thể viết vectơ <unsigned char> vào tập tin, theo sau là một số không dấu int

enter image description here

#define random(x) (rand()%x) 
std::ofstream filewrite("abc.raw", std::ios::out | std::ofstream::binary); 
unsigned int iter = 0; 
unsigned int data_length=5; 
unsigned int ID_data=0; 
//-------------Write data-------------// 
while (iter<10){ 
    vector<unsigned char> vec_data; 
    for (unsigned int i=0;i<data_length;i++){ 
     vec_data.push_back(random(256)) 
    }   
    std::copy(vec_data.begin(), vec_data.end(), std::ostreambuf_iterator<char>(filewrite)); 
    //Write ID_data after vec_data 
    filewrite.write(reinterpret_cast<const char *>(&ID_data), sizeof(ID_data)); 
    ID_data++; 
    iter++; 
} 
filewrite.close(); 

Trong bổ sung, tôi muốn trích xuất các dữ liệu vào vector mà không có ID nhóm. Đây là mã của tôi để trích xuất dữ liệu từ tệp ở trên, nhưng nó không loại bỏ nhóm ID. Bạn có thể giúp tôi xóa nó không?

//-------------Read data-------------// 
std::ifstream file("abc.raw", std::ios::binary); 
// Stop eating new lines in binary mode!!! 
file.unsetf(std::ios::skipws); 

// get its size: 
std::streampos fileSize; 

file.seekg(0, std::ios::end); 
fileSize = file.tellg(); 
file.seekg(0, std::ios::beg); 

// reserve capacity 
std::vector<unsigned char> vec; 
    vec.insert(vec.begin(), 
std::istream_iterator<unsigned char>(file), 
std::istream_iterator<unsigned char>()); 
+0

Nếu mã này đang làm việc, sau đó tôi đoán bạn nên yêu cầu nó trong phần Mã Review. –

+2

Thay vì đưa ra một giải thích về những gì đang xảy ra, hãy cung cấp các quan sát. Câu hỏi của bạn không rõ ràng. –

+4

@MehrdadMomeny Nửa đầu của câu hỏi không rõ liệu nó có hoạt động hay không. Phần thứ hai chắc chắn ** không ** hoạt động như dự định, vì vậy [codereview.se] sẽ không phù hợp vào lúc này. Ngoài ra, chúng tôi không phải là "phần": p – Kaz

Trả lời

2

Trước hết, bạn sử dụng while, nơi for sẽ dễ dàng hơn để đọc. BTW. bạn không cần hai biến lặp. Bạn có thể lặp lại qua ID_data.

for(unsigned int ID_data = 0; ID_data < 10; ++ID_data) { 
    // ... 
} 

thứ hai bạn không cần tạo ra vectơ mà bạn không bao giờ sử dụng lại, sau đó viết các phần tử. Nó là tốt làm trực tiếp viết các giá trị.

for(unsigned int ID_data = 0; ID_data < 10; ++ID_data) { 
    for(unsigned int i = 0; i < data_length; i++) 
     filewrite.put(random(256)); 

    filewrite.write(reinterpret_cast<const char *>(&ID_data), sizeof(ID_data)); 
} 

Phần thứ hai: Bạn có thể khởi tạo véc tơ với hai trình lặp.

auto vec = std::vector<unsigned char>(std::istream_iterator<unsigned char>{file}, 
             std::istream_iterator<unsigned char>{}); 

Nhưng kể từ khi bạn muốn chỉ đọc data_length giá trị mà bạn có thể thích:

auto vec = std::vector<unsigned char>{}; 

while(file) { 
    for(unsigned int i = 0; i < data_length; i++) { 
     char c; 
     if(!file.get(c)) 
      break; 
     vec.push_back(static_cast<unsigned char>(c)); 
    } 

    unsigned int ID_data; 
    file.read(reinterpret_cast<const char *>(&ID_data), sizeof(ID_data)); 
    // we don't use ID_data here, so it will simply be ignored. 
} 
+0

Cảm ơn nhưng nó có lỗi như & std :: basic_istream > :: get (std :: basic_streambuf > &, _ Elem) ': không thể chuyển đổi đối số 1 từ' unsigned char 'to' char & và lỗi C2664: 'std :: basic_istream > & std :: basic_istream > :: đọc (_Elem *, std :: streamize)' : không thể chuyển đổi đối số 1 từ 'const char *' thành 'char *' Tôi nghĩ rằng nó phải là tệp.read (reinterpret_cast (& ID_data), sizeof (ID_data)); và char c; – Jame

+0

Tôi đã thay đổi câu trả lời của mình cho phù hợp. Điều này sẽ hoạt động ngay bây giờ. – cdonat

2

Tôi không chắc chắn rằng tôi đã hiểu chính xác câu hỏi của bạn. Vì tôi giả sử rằng bạn đang gặp vấn đề với việc viết mã nhị phân, tôi đang cung cấp cho bạn một giải pháp cho chỉ một vectơ. Bạn có thể sửa đổi nó một cách dễ dàng:

void Write(std::ostream& os, const std::vector<std::uint8_t>& v, const std::int32_t id) 
{ 
    std::size_t len = v.size(); 
    os.write((const char*)&len, sizeof len); 
    for (auto e : v) 
    os.write((const char*)&e, sizeof e); 
    os.write((const char*)&id, sizeof id); 
} 

void Read(std::istream& is, std::vector<std::uint8_t>& v) 
{ 
    std::size_t len; 
    is.read((char*)&len, sizeof len); 
    v.resize(len); 
    for (auto &e : v) 
    is.read((char*)&e, sizeof e); 
    std::int32_t id; 
    is.read((char*)&id, sizeof id); 
} 

int main() 
{ 
    // write 
    { 
    std::ofstream os("abc.raw", std::ios::binary); 
    if (! os) 
     return -1; 
    std::vector<std::uint8_t> v; 
    v.push_back(0x10); 
    v.push_back(0x20); 
    v.push_back(0x30); 
    Write(os, v, 0x123); 
    } 

    // read 
    { 
    std::ifstream is("abc.raw", std::ios::binary); 
    if (! is) 
     return -1; 
    std::vector<std::uint8_t> v; 
    Read(is, v); 
    } 

    // 
    return 0; 
} 
+0

Làm thế nào về câu hỏi thứ hai về trích xuất dữ liệu thô mà không có ID – Jame

+0

Chỉ cần đọc id và loại bỏ nó. – ZDF

+1

@ user8430 Xem ví dụ được cập nhật. – ZDF

Các vấn đề liên quan