Having trouble with vectored structures

Started by
13 comments, last by Zahlman 16 years, 9 months ago
Maybe it's just me, but I can't seem to get this to work. I'm trying to read structures from a file, while storing them in a vector, as I only know how many structures there are after reading the header. This is how I read in the structures;

where 'resc_list' is a vector, declared as 'std::vector<Resource> resc_list;'

for(uint32_t i=0;i<resource_count;++i)
{
   Resource r;
   in >> r.file_offset;
   in >> r.resource_size;
   in >> r.resource_name;

   resc_list.push_back(r);
}

However, I find that when I come to try to read anything from the vector, it's completely empty! Any ideas what might be wrong?
Advertisement
Have you checked the value of resource_count?
- Have you checked the value of resource_count?
- Have you checked the contents of the file?
- Are you opening the file in a way that's compatible with how you intend to interpret its contents (i.e. you usually want to use text mode when you read with operator>>, and binary mode when you read with .read())?
- How are you checking the contents of the vector? Are you sure the loading code has already run when you do this check?
- Are you communicating (passing) the vector between functions? If so, how?
Quote:Original post by Zahlman
- Have you checked the value of resource_count?
- Have you checked the contents of the file?
- Are you opening the file in a way that's compatible with how you intend to interpret its contents (i.e. you usually want to use text mode when you read with operator>>, and binary mode when you read with .read())?
- How are you checking the contents of the vector? Are you sure the loading code has already run when you do this check?
- Are you communicating (passing) the vector between functions? If so, how?
In defense of my admittedly more brief reply, I'd like to mention that answering the first question should lead the OP naturally to the others listed (which is why I left it at that).

For the benefit of the OP I'll elaborate a bit. First of all, simply checking the value of resource_count (e.g. in the debugger, by way of debug output, etc.) should tell you something about whether the code is being executed in the first place. If at that point resource_count is found to be zero, it's probably a good guess that the file doesn't contain what you think it does, you're interpreting its contents incorrectly, or you're computing the value of resource_count incorrectly. If resource_count is not zero, resc_list.size() must, for all practical purposes, return a non-zero value once the loop has terminated. If you're finding that it is returning zero, then you're checking it in the wrong place, passing the vector to the function incorrectly, or something of that sort.

@The OP: There are a couple of useful lessons to be learned here. First, although it's good not to overwhelm us with code when posting to the forums, it's usually best to provide a little more context than in your example (what are the function arguments? how are they passed? are there global variables involved? from where is the code invoked? etc.). Second, the process of which I gave an example earlier in this post is called 'debugging', and is a skill that is every bit as important to a programmer as being able to write the code in the first place. As you develop this skill, you'll find that these sorts of problems are, in most cases, fairly straightforward to solve.
Yeah, I did check both the vectors size, and the value of resource_count, showing that resource_count was very large, while the size of the vector was 0. The snippet of code I showed, is part of the Load function of a class.

The class header;
class BIGFile{    protected:        struct Resource{            uint32_t file_offset;            uint32_t resource_size;            std::string resource_name;        };        uint32_t resource_count;        std::vector<Resource> resc_list;        std::string file;        std::string dest;        std::ifstream in;    public:        BIGFile(std::string file,std::string dest):file(file),dest(dest){}        ~BIGFile();        void Load();//loads the file with the given name        uint32_t GetCount(){return resource_count;}        uint32_t GetVecSize(){return resc_list.size();}        std::string GetNames();//returns a string of the filenames, seperated by spaces        void Extract(std::string,std::string);//extracts the named resource to the given location};


and the whole Load function;
void BIGFile::Load(){    in.open(file.c_str());    if(in.is_open())    {        char id[4];        in.get(id,4);        if(std::string("BIG4").compare(id)==0)        {            int x;            in >> x;            in >> resource_count;            in >> x;            for(uint32_t i=0;i<resource_count;++i)            {                Resource r;                in >> r.file_offset;                in >> r.resource_size;                in >> r.resource_name;                resc_list.push_back(r);            }        }    }}


As you can probably see, it's a class for reading Command & Conquer archive files, and the Load function opens the file with the name that the class is constructed with.

EDIT: I've tried changing the original snippet to use in.read() and a string buffer (sbuff), as follows;
for(uint32_t i=0;i<resource_count.u;++i){   Resource r;   in.read(r.file_offset.c,sizeof(uint32_t));   in.read(r.resource_size.c,sizeof(uint32_t));   in.get(sbuff,'\0');   r.resource_name = sbuff.str();   resc_list.push_back(r);}


but still no luck.

[Edited by - webwraith on July 13, 2007 1:47:48 PM]
You said you checked the value of resource_count... did you actually step through the loop in the debugger to verify that push_back was being called over and over again?

Your code looks fine as it is, but there must be something else going on that could only be determined by you stepping through with a debugger, or by posting more code surrounding the loop.
There are several issues at play here, but for now I just have one question: Are you positive that the line:
in >> resource_count;
Is being executed, and if so, how do you know that this is the case?
I'm not conversant with the MingW debugger, but when I run the Debug command from the IDE(Code::Blocks) it runs through the program, then exits, saying there's nothing wrong.

OK, I tried setting the resource counter to 0, and it came through at the end as 0, I'm going to go check that file, now...

EDIT: OK, just found out that std::string::compare() isn't recognizing the "BIG4" at the start of the file. It's in the file (I just checked), so am I wrong in putting it like this;
if(std::string("BIG4").compare(id)==0)


Where id is now declared
char id[5];
My advice would be to get familiar with a debugger. You won't be very productive if you have to make random guesses as to what's wrong, or always resort to "printf" debugging.

Stepping through your code with a debugger will probably tell you the problem in a few seconds.
Quote:Original post by webwraith
EDIT: OK, just found out that std::string::compare() isn't recognizing the "BIG4" at the start of the file. It's in the file (I just checked), so am I wrong in putting it like this;
if(std::string("BIG4").compare(id)==0)


Where id is now declared
char id[5];


You keep changing your posts :-)
When I hit reply, it was "char id[4]", and now its "char id[5]" :-)

Well, that's an improvement. Are you sure it's being null-terminated?

This topic is closed to new replies.

Advertisement