C Strings (ugh)

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

Recommended Posts

I am not good with strings in C, please tell me how you would go about the solution: Textures are loaded into a game engine, and if the filename(s) provided starts with an underscore ('_') it is interpreted as an animation. The name of the animation is provided as a string and follows the template "_name_nnn.ext", where nnn is a three-digit number containing the number of frames in the animation, and ext is the file extension. The corresponding animation frames are named similarly, e.g. "_name_000.ext" would be the first frame. How would you extract the number of frames from the string? How would you construct a string for the filename of each animation frame? Currently my code is a mess and I just think I'm going about it the wrong way. I dare not show the original function this came from, so I've made a sample program outlining the current state of things, take a look:
int main (void)
{
char strGivenName[256], strFrameName[256];
char strNumFrames[4], strFileExtension[4];
int i, intNumFrames;
size_t fnlen;

// clear arrays
memset (strNumFrames, NULL, 4);
memset (strFileExtension, NULL, 4);

// This will be the filename provided
strcpy (strGivenName, "data/textures/_animation_030.png");

// Get string lenth so we can extract frame count and extension later
fnlen = strlen (strGivenName);

// Copy frame count only into another string
strncat (strNumFrames, &strGivenName[fnlen-7], 3);

// Then use sscanf to convert to integer
sscanf (strNumFrames, "%d", intNumFrames);

// Then save the file extension to another string
strncat (strFileExtension, &strGivenName[fnlen-3], 3);

// Now we have the information needed to produce the actual filenames
for (i = 0; i < intNumFrames; i++)
{
// Start out with filename provided
strcpy (strFrameName, strGivenName);

// Overwrite the last 7 characters with frame number and extension
sprintf (&strFrameName[fnlen-7], "%.3d.%s", i, strFileExtension);
printf ("%s\n", strFrameName);
}

return (0);
}



Share on other sites
int frame;char num[4];const char * c = strstr( filename, ".ext" );num[0] = *(c-3);num[1] = *(c-2);num[2] = *(c-1);num[3] = 0;frame = atoi( num );

You may need to toy with it, do some things to prevent crashes like make sure c - 3 isn't less than filename's start.

Share on other sites
Hey thanks for reply looks good, is atoi() portable?

Share on other sites
Yes, it is. (beware: itoa() is not.)

Share on other sites
Quote:
 Original post by HexedHey thanks for reply looks good, is atoi() portable?

atoi is part of the standard C library, so it's pretty well supported.

Share on other sites
Quote:
 Original post by SneftelYes, it is. (beware: itoa() is not.)

Oh yea that's what I was thinking of. Thanks guys.

Share on other sites
Well... I would do it in C++ instead (or even better, some other language) :)

But just for educational purposes, let's do it the really hard (but clean - there's really no sense copying things around that much) way:

int main() {  char* input = "data/textures/_animation_030.png";  char* name, *nameindex;  int id = 0;  char* searcher = input;  while (*++searcher); /* find end of string */  name = nameindex = malloc(searcher - input);  if (!name) return -1; /* couldn't grab that memory :( */  /* the difference basically gives us the strlen(). The name can't be any   * longer than the context from which it was fetched */  while (*--searcher != '/'); /* now positioned at last slash */  ++searcher; /* skip slash; now positioned on underscore */  while ((*nameindex++ = *++searcher) != '_'); /* copy to underscore */  *--nameindex = '\0'; /* overwrite the underscore */  /* Now searcher is on the second underscore */  while (*++searcher >= '0' && *searcher <= '9') {    id = 10 * id + (*searcher - '0');  }  printf(name);  printf("\n%d\n", id);  free(name);}

I had 3 problems the first time I typed this in: missing * on nameindex (thus it was the wrong type, producing compile errors), missing guard for the malloc call (this isn't c++ with it's fancy exceptions), and missing free() (bad programmer, no cookie).

Share on other sites
Hey Zahlman, I think I'll stick with C. Thanks for the added perspective, I love seeing different ways of accomplishing a common goal.

Share on other sites
A better solution to your problem would be to use a header at the beginning of your file.

e.g.

Magic - 4 bytes of char to indicate file type

if Magic=="ANIM" then
{
Next 4 bytes are length of header
next 4 bytes are frame count
array of offsets to each frame
}
if Magic=="MESH" then
{
...
}
...

So your file would look something like this (I've put actual numbers in {})
ANIM{0x00000100}{0x0000000C}{0x00000100}{0x00000230}{0x00000450}....

Share on other sites
True, data type should normally be indicated in the file format - however it appears here that "animation" doesn't describe the physical type of data (it's a .png), but instead a logical type - what the data will be used for.

In any case, the parsing problem is likely to persist.

1. 1
Rutin
36
2. 2
3. 3
4. 4
5. 5

• 12
• 14
• 9
• 9
• 14
• Forum Statistics

• Total Topics
633344
• Total Posts
3011438
• Who's Online (See full list)

There are no registered users currently online

×