user1594121
user1594121

Reputation: 117

Working with structs?

I'm having trouble working with strings (char*) in structs. I can't seem to call the right data I want too.

Under processFile it shows the struct member correctly; under main it does not.

Here is my code:

#include <iostream>
#include <io.h>
#include <string>
#include "dirent.h"
#include "Stream.h"
#include "Compression.h"
#include "Definitions.h"

using namespace std;
using namespace System::IO;
using namespace System::Funcs;

bool isRawfile(char* ext);
void ProcessDirectory(string directory);
void ProcessFile(char* file);
void ProcessEntity(struct dirent* entity);

typedef struct
{
    char *name;
    int usize;
    int csize;
    BYTE *data;
} rawfile;

string path = "";
string source;
int numrawfiles = 0, numstringtables = 0;
rawfile *rawfiles = new rawfile[0x400];

FILE * zone = fopen( "C:\\Users\\jake\\Desktop\\patch_mp.zone" , "wb" );

int main(int argc, char **args)
{
    if(args[1] != NULL)
    {
        source = string(args[1]) + "\\"; //maybe move under else here..
        if(strchr(args[1], '.') != NULL)
        {
            cout<<"Unable to compile files, please drag a folder to compile."<<endl;
            cin.get();
            return 0;
        }
        else
        {
            int header[] = {1,0,0x3B4,0,0,0,1,0,0x1000,0,0,0,-1};
            for(int i=0; i<13; i++)
                fwrite(Converter::Int32ToBytes(header[i]), 1 , 4 , zone );

            ProcessDirectory(args[1]);

            for(int i=0; i<numrawfiles; i++)
                cout<<"Name: "<<rawfiles[i].name<<" Length: "<< rawfiles[i].usize << " - in main()"<<endl;

            fclose(zone);
        }
    }
    else
    {
        cout<<"No folder selected to compile. Press any Key to quit."<<endl;
        cin.get();
        return 0;
    }
    cin.get();
    return 0;
}

void ProcessDirectory(string directory)
{
    string dirToOpen = path + directory;
    auto dir = opendir(dirToOpen.c_str());
    path = dirToOpen + "\\";
    if(NULL == dir)
    {
        cout << "could not open directory: " << dirToOpen.c_str() << endl;
        return;
    }
    auto entity = readdir(dir);
    while(entity != NULL)
    {
        ProcessEntity(entity);
        entity = readdir(dir);
    }
    path.resize(path.length() - 1 - directory.length());
    closedir(dir);
}

void ProcessEntity(struct dirent* entity)
{
    if(entity->d_type == DT_DIR)
    {
        if(entity->d_name[0] == '.')
            return;

        ProcessDirectory(string(entity->d_name));
        return;
    }

    if(entity->d_type == DT_REG)
    {
        string fullpath = path + entity->d_name;
        ProcessFile(const_cast<char *>(fullpath.c_str()));
        return;
    }
    cout << "Not a file or directory: " << entity->d_name << endl;
}

void ProcessFile(char* file)
{
    char* extension = strrchr(file, '.');

    if(isRawfile(extension))
    {
        rawfile raw;
        raw.name = (char *)&file[source.length()];
        raw.usize = File::getFileSize(file);
        rawfiles[numrawfiles] = raw;
        cout<<"Name: "<<rawfiles[numrawfiles].name<<" Length: "<< raw.usize << " - in ProcessFile()"<<endl;
        fwrite(Converter::Int32ToBytes(0x23),1,4,zone);
        fwrite(Converter::Int32ToBytes(-1),1,4,zone);
        numrawfiles++;
    }
}

bool isRawfile(char* ext)
{
    char *exts[11] = {".gsc",".cfg",".txt",".news",".png",".vision",".rmb",".script",".arena",".atr",".csc"};
    for(int i=0; i<10; i++)
        if(strncmp(ext,exts[i],strlen(exts[i]))==0)
            return true;
    return false;
}

Here is an example picture: http://puu.sh/2vYt7/7698fd05f1

What am I doing wrong?

Upvotes: 0

Views: 302

Answers (3)

JazzyWhit
JazzyWhit

Reputation: 411

To add to what scd said, you are not successfully dereferencing the name member. When you try and operate on things[1].name you are operating on a pointer, which is simply a memory location.

This is one of the trickiest things when learning to use pointers. Here is some more reading on the dereference operator, and syntax hints.

http://en.wikipedia.org/wiki/Dereference_operator#Other_syntax

Edit:

After compiling myself, I realized that I was on the wrong track with this one, and that std::cout will correctly handle the char pointer. You should be able to solve this with your code, just ensure that you give your struct array a size.

This worked for me:

#include <iostream>
#define MAXSIZE 3

typedef struct
{
   char* name;
   int age;
}Thing;

Thing *things = new Thing[MAXSIZE];

int _tmain(int argc, _TCHAR* argv[])
{
char* names[MAXSIZE] = { "Alice", "Ben", "Carlos" };
    int ages[MAXSIZE] = { 24, 25, 26 };
    for(int i=0; i<MAXSIZE; i++)
    {
        things[i].name = names[i];
        things[i].age = ages[i];
    }
    std::cout << things[1].name << std::endl;
    return 0;
}

Upvotes: 0

juanchopanza
juanchopanza

Reputation: 227390

Save yourself a lot of trouble by using an std::string:

#include <string>
struct thing
{
   std::string name;
   int age;
};

You can also avoid the dynamically allocated array:

#include <vector>
std::vector<thing> things(3);

Upvotes: 4

scd
scd

Reputation: 164

You are outputting the memory address of "Ben" instead of the actual String. You should use

cout << things[1]->name << endl;

which is syntactic sugar for

cout << (*things[1]).name << endl;

Upvotes: 0

Related Questions