1

I have such piece of code:

typedef struct reader
{
    char name[50];
    char card_num[50];
    char title[100];
}reader_t;
int main()
{
    vector<reader> vec;
    ifstream input_file("D:\\lab.txt", ios::binary);
    reader_t master[1];
    input_file.read((char*)&master, sizeof(master));

    for (size_t idx = 0; idx < 1; idx++)
    {
        reader temp;
        strcpy(temp.name, master[idx].name);
        strcpy(temp.card_num, master[idx].card_num);
        strcpy(temp.title, master[idx].title);
        vec.push_back(temp);

        cout << "Name: " << master[idx].name << endl;
        cout << "Card num: " << master[idx].card_num << endl;
        cout << "Title: " << master[idx].title<<endl;

    }
    cout << vec.size();

    getchar();
}

What is does: it reads structures from binary file into an array of structures,copies them into vector and displays structure.And yes, I do need to do like this - I need to store structures from file in vector and this is the only working way to do it I could find(if you can tell, how to read structures to vector directly from file - you are welcome).

So,everything works fine, but the problem is that I need to create a function which would be able to do the same, but with dynamic array.I wrote something like this:

void read_structs(int vec_size)
{
     ifstream input_file("D:\\lab.txt", ios::binary);

     //Here I commented 2 ways how I tried to create a dynamic array of structs
     //reader* master = new reader[vec_size];
     //reader* master = (reader*)malloc(sizeof(reader) * vec_size);

    input_file.read((char*)&master, sizeof(master));
    for (size_t idx = 0; idx < vec_size; idx++)
    {

        reader temp;
        strcpy(temp.name, master[idx].name);
        strcpy(temp.card_num, master[idx].card_num);
        strcpy(temp.title, master[idx].title);
        vec.push_back(temp);

        cout << "Name: " << master[idx].name << endl;
        cout << "Card num: " << master[idx].card_num << endl;
        cout << "Title: " << master[idx].title<<endl;

    }
 }

And that worked fine too unless I tried to run it.VS wasn't higlighting error in my code, it just was throwing an exception right as the moment when the program tried to access master[0].name.

10
  • What is value of vec_size ? Commented Apr 24, 2017 at 10:54
  • @ameyCU when I run the program I use 1 Commented Apr 24, 2017 at 10:55
  • 4
    Just use std::vector Commented Apr 24, 2017 at 10:56
  • 1
    No, what you've written in the post is that you don't understand how to use std::vector for a certain purpose. That's the easiest limitation to overcome, read the documentation. Commented Apr 24, 2017 at 10:59
  • 1
    unrelated, struct reader {...}; is enough in C++, typedef version is C legacy. You even mess with reader and reader_t names in your example Commented Apr 24, 2017 at 11:13

1 Answer 1

4
  1. There is absolutely no point in the temp struct. See, the

    vec.push_back(temp);
    

    is already using copy constructor, so copy constructor must work and then the set of strcpy is not doing anything different from that, so just go with

    vec.push_back(master[0]).
    
  2. You can't read into vector directly. You do need to read into temporary. So that is correct. Except I suppose you want to read all entries from the file no matter how many of them there are, so you need to put the read itself also into the loop.

  3. There is not much point in creating an array of one element.

    reader_t master[1];
    input_file.read((char*)master, sizeof(master));
    //                     ^ you *don't* need & here, arrays degrade to pointers automatically
    

    and

    reader_t master;
    input_file.read((char *)&master, sizeof(master));
    //                      ^ but you do need & here.
    

    are equivalent. I would go with the later.

  4. So we are basically down to:

    reader temp; // calling it temp; the master name makes no sense.
    while (input_file.read((char*)&temp, sizeof(temp)))
    // read returns input_file and input_file is false if last operation failed
    {
        vec.push_back(temp);
    
        // verify the stored values by reading back vfrom vec.back().
        cout << "Name: " << vec.back().name << endl;
        cout << "Card num: " << vec.back().card_num << endl;
        cout << "Title: " << vec.back().title<<endl;
    }
    
  5. In the second example, you didn't initialize master, so it obviously crashed.

  6. There is a more C++ approach though. First, you define a read operator for the structure:

    std::istream &operator>>(std::istream &in, reader &r) {
        return in.read((char *)&r, sizeof(r));
    }
    

    and then you simply read the vector using the istream_iterator:

    vec.assign(std::istream_iterator<reader>(input_file),
               std::istream_iterator<reader>());
    

    and the standard library will generate the above loop for you.

Sign up to request clarification or add additional context in comments.

7 Comments

yep that is what i said in comment, ty for typing it out in steps. Idk if you initialized master somewhere else. Else you need to print with temp.name etc.. and you dont need master anymore.
or print with the vector like the edit is also an option.
@NightStallion, you'll have to do some debugging. Does the file actually have all the bytes? Remember, it is exactly 50 bytes for name, exactly 50 bytes for card_num and exactly 100 bytes for title. If you meant newline-terminated or something, you'll need to do correct formatted input in the operator>>.
@JanHudec yep,exactly 200 bytes
@JanHudec well,I tried to do like you wrote in 6th paragraph,but I get this error:C2664: "std::_Vector_iterator<std::_Vector_val<std::_Simple_types<reader>>> std::vector<reader,std::allocator<_Ty>>::insert(std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<reader>>>,unsigned int,const _Ty &)": can not convert argument 1 from "std::istream_iterator<reader,char,std::char_traits<char>,ptrdiff_t>" into "std::_Vector_const_iterator<std::_Vector_val<std::_Simple_types<reader>>>"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.