2016-01-12 15 views
8

Muszę grupować wektory 5unsigned char (data_length=5). Na końcu grupy chcę dodać grupę ID i zapisać je (dane grupy + jej identyfikator) do pliku. W którym typie grupy jest ID integer. Wykonuję to zadanie jak poniżej kod. Czy to jest poprawne? mieszek rysunek pokazuje co BioręJak mogę zapisać wektor <unsigned char> do pliku, a następnie unsigned 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(); 

W dodatkami, chcę, aby wyodrębnić dane bez wektor ID grupy. To jest mój kod do wyodrębniania danych z powyższego pliku, ale nie usuwa on grupy ID. Czy możesz mi pomóc go usunąć?

//-------------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

Jeśli ten kod działa, to chyba należy poprosić go w sekcji Code Review. –

+2

Zamiast podawać interpretację tego, co dzieje się nie tak, należy przedstawić obserwacje. Twoje pytanie jest niejasne. –

+4

@MehrdadMomeny W pierwszej połowie pytanie nie jest jasne, czy to działa, czy nie. Druga część jest zdecydowanie ** nie ** działa zgodnie z przeznaczeniem, więc [codereview.se] byłoby niewłaściwe w tej chwili. Ponadto nie jesteśmy "sekcją": p – Kaz

Odpowiedz

2

Przede wszystkim, należy użyć while, gdzie for byłoby łatwiejsze do odczytania. BTW. nie potrzebujesz dwóch zmiennych iteracyjnych. W porządku jest iterowanie nad ID_data.

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

sekund Nie trzeba tworzyć wektora, którego nigdy nie użyjesz ponownie, a następnie napisać elementy. Dobrze jest pisać bezpośrednio wartości.

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

Druga część: Można utworzyć instancję wektorową z dwoma iteratorami.

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

Ale skoro chcesz tylko czytać data_length wartości może wolisz:

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

Dzięki, ale ma błąd jako & std :: basic_istream > :: get (std :: basic_streambuf > &, _ Elem) ': nie można przekonwertować argumentu 1 z' unsigned char 'to' char & and error C2664: 'std :: basic_istream > & std :: basic_istream > :: przeczytaj (_Elem *, std :: stream) : nie można przekonwertować argumentu 1 z "const char *" na "char *" Myślę, że musi to być file.read (reinterpret_cast (& ID_data), sizeof (ID_data)); i char c; – Jame

+0

Zmieniłem odpowiednio odpowiedź. To powinno działać teraz. – cdonat

2

Nie jestem pewien, czy poprawnie zrozumiałem Twoje pytanie. Ponieważ zakładam, że masz problemy z pisaniem binarnym, daję ci rozwiązanie tylko dla jednego wektora. Można go łatwo modyfikować:

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

Co powiecie na drugie pytanie o wyodrębnianie surowych danych bez identyfikatora – Jame

+0

Po prostu odczytaj identyfikator i odrzuć go. – ZDF

+1

@ user8430 Zobacz zaktualizowany przykład. – ZDF

Powiązane problemy