0

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?

9
  • 2
    How about: thing *things = new thing[3]; Commented Apr 7, 2013 at 21:18
  • Yeah I understand that, this is a psuedo. But that array could be of any length, In that case am I doing it correctly? Commented Apr 7, 2013 at 21:20
  • Don't post pseudo-code, it only leads to misunderstandings. But anyway your pseudo-code is fine, the error must be somewhere in the real code. Commented Apr 7, 2013 at 21:21
  • My real code is many lines longer and honestly I would consider it would lead to only more confusion. I'll try working it out again. Commented Apr 7, 2013 at 21:23
  • @user1594121 Try to cut it down as much as possible before posting, but obviously not so much that you get rid of the error. If you do this, there's a reasonable chance you'll discover the error yourself, and probably learn something in the process. Commented Apr 7, 2013 at 21:25

3 Answers 3

4

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);
Sign up to request clarification or add additional context in comments.

2 Comments

Yeah I can use that but I wanted to take more of a C approach. I'm still looking for my error though.
Want to make a C approach? Write C and don't irritate C++ programmers.
0

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;

2 Comments

This is wrong, the compiler wouldn't even allow mixing up . and ->.
like lets say the string was "erica", instead of the hex for that it would be like 0x0D 0x0D 0x0D 0x0D 0x0D. If that makes sense?
0

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

3 Comments

Can I email you with my whole code? I'm attempting this but it seems to work (cout) inside of the function it's defining the data, but when I call from an outside void it show's as different chars.
How about you give us an idea of which compiler you are using, so we can dig deeper into what is causing the problem.
My IDE is visual studio, I'm using Win32 C++. I updated the source with my whole code if you haven't seen it already.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.