Jump to content
  • Advertisement
Sign in to follow this  
Decrius

[C(++)] strings in file to string in memory

This topic is 3766 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This should be sort of easy but I cannot grasp it... I have a file with content, the content has an 'array' of strings (just strings seperated by 0x00). I want those strings to be put in an array of char * so I can handle it further. How can I read out the buffer of the loaded file and put the strings in the array? I got it working, but not fully. I also want to add "data/" infront and ".png" at the end. int size = number of textures in the file char *buffer = an allocated piece of memory filled with the complete content of the file
char *textures[size];
                for (int i = 0; i < size; i++)
                {
                    textures = buffer;
                    while (*buffer != 0x00)
                    {
                        *buffer += 96;
                        buffer++;
                    }
                    buffer++;
                    std::cout << textures << "\n";
                }

                world_textures->load_textures(size, textures);
I prolly have to rewrite it to add "data/" and ".png", but how would you do that? I get confused with the pointers if its about char * ... :( Thanks, Decrius

Share this post


Link to post
Share on other sites
Advertisement
Short answer: do it the 'hard way' (e.g. using pointers and manual memory management and C-library functions such as strcpy() and strcat()) as an exercise, then set all that aside and use std::string instead. The latter will take care of the memory management aspect of things for you, and will allow you to write more intuitive statements such as:
path = "data/" + name + ".png";
If the file is in text format, you should be able to simply extract the file names from the stream using the >> operator. If the file is binary, it's a little more complicated; in this case, I'd recommend using an existing solution such as the Boost Serialization library.

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Short answer: do it the 'hard way' (e.g. using pointers and manual memory management and C-library functions such as strcpy() and strcat()) as an exercise, then set all that aside and use std::string instead. The latter will take care of the memory management aspect of things for you, and will allow you to write more intuitive statements such as:
path = "data/" + name + ".png";
If the file is in text format, you should be able to simply extract the file names from the stream using the >> operator. If the file is binary, it's a little more complicated; in this case, I'd recommend using an existing solution such as the Boost Serialization library.


Yes, the hard way please :P. Since the texture loading function is written for char* arrays (wrote it myself) and I prefer C for some things, I need the output in the standard C format...

I can work with strcpy and strcat with normal character strings, but this is an array of pointers to character strings...not sure how to handle that...

Thanks anyways,

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Yes, the hard way please :P. Since the texture loading function is written for char* arrays (wrote it myself)


Wrote it yourself? Then you can rewrite it to use std::string just as easily. But let's say for the sake of argument that you Didn't write the texture loading function. You can still use your function by calling std::string::c_str which returns a const char * that you can pass to functions that take const char *. You did write your function to be const correct at least, right? As for this:

Quote:
and I prefer C for some things, I need the output in the standard C format...


that's your prerogative, but you're really just hurting yourself and opening yourself up for a lot of easily avoidable bugs by not using std::string and likely the rest of the C++ Standard Library. Good luck with your project!

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Yes, the hard way please :P. Since the texture loading function is written for char* arrays (wrote it myself) and I prefer C for some things, I need the output in the standard C format...


Well... let's get this done.


char *textures[size] = {0};

try
{
for (int i = 0; i < size; ++i, ++buffer)
{
const char *original = buffer;
while (*buffer != 0x00)
*buffer++ += 96;

const std::size_t len =
strlen(original) + strlen("data/") + strlen(".png") + 1;
textures = new char[len];

strncpy(textures, "data/", len);
assert(strlen("data/") < len);

strncat(textures, original, len - strlen(textures) - 1);
strncat(textures, ".png", len - strlen(textures) - 1);
}

world_textures->load_textures(size, textures);
}

catch(...)
{
for (int i = 0; i < size; ++i)
delete [] textures;
}

for (int i = 0; i < size; ++i)
delete [] textures;


Share this post


Link to post
Share on other sites
I have a feeling that the code ToohrVyk posted looks an awful lot like most implementations of std::string's operator+... [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by MJP
I have a feeling that the code ToohrVyk posted looks an awful lot like most implementations of std::string's operator+... [smile]


Actually, no, it doesn't: it's more complex than that. I suspect most implementations of std::string concatenation (operator+=) would look something like this:

template<typename It> // Assumed Random-Access iterator
void append(It begin, It end)
{
std::size_t full = size + std:distance(begin, end);
if (full > self.capacity)
{
detail::buffer other(full);
std::copy(self.data, self.data + size, other.data);
std::swap(self, other);
}

std::copy(begin, end, self.data + size);
size = full;
}


Where 'buf' is a thin RAII wrapper around a buffer of characters.

Share this post


Link to post
Share on other sites
Well, I guess this shows how much I know. :P

Thanks, ToohrVyk.

Share this post


Link to post
Share on other sites
Quote:
Original post by ToohrVyk
Quote:
Original post by Decrius
Yes, the hard way please :P. Since the texture loading function is written for char* arrays (wrote it myself) and I prefer C for some things, I need the output in the standard C format...


Well... let's get this done.

*** Source Snippet Removed ***


Thank you :), it works, now I'll examine what I did wrong :P

What does assert() do exactly? Yes, it can throw the exception, but it checks if the string is copied from one to another in this case?

Share this post


Link to post
Share on other sites
Quote:
I want those strings to be put in an array of char *


This is sort of like saying "I want those eggs to be put in a carton of eggshells which contain yolks and whites". If you have strings, why not put them in an array of, well, strings? A char* is not a string. It's a pointer; it points to some chunk of memory, where you write some sequence of characters, and do all the memory management.

Quote:
Since the texture loading function is written for char* arrays (wrote it myself)


If you wrote it yourself, you can fix it.

Quote:
and I prefer C for some things,


You prefer making things harder for yourself for no reason?

Quote:
I need the output in the standard C format...


(a) Not if you fix the function, you don't.
(b) You can always get at the underlying "const char *" representation of a string object with its .c_str() member function, nice and simple.

BTW, why on earth are you adding 96 to each character as you go? Some kind of "encryption"? Please, don't make me laugh. And what are you going to do if you want a string to actually contain ASCII character 96 (a backtick, `)? Then you'd have a zero byte in the file, and wouldn't be able to distinguish it from a null terminator.

And for that matter, why not just cut up the file as you read it (use the free function std::getline() to read into a std::string object; you can specify the 'delimiter' of your "line" to be a zero byte)?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!