Advertisement

"Un-terminated strings"

Started by June 06, 2000 10:12 AM
8 comments, last by Orpheum 24 years, 6 months ago
Can an "un-terminated string" cause problems in another, presumeably unrelated, portion of a program? Here''s where I suspect the problem lies - I pass a string into setMapName(), with it''s length, and then new some memory void GDIMapGen::setMapName(char* szName, int iSize) { szMapName = new char[iSize + 1]; strcpy(szMapName, szName); iMapNameSize = iSize + 1); //+1 for \0 } But when I later try to view the contents of the string in Visual Studio 6''s debugger, I see "test.map" (or whatever is in the string) in the variable watcher thingy. When I click the + to expand the string view, all I see is the first letter of the string. Its almost looks like szMapName == ''t'' rather than szMapName[0] == ''t'', while szMapName == "test.map". Strcpy() should insert a null char at the end of the string so you would THINK there wouldnt be a problem. Here''s the lowdown on my problem... My map generator tool outputs a map file so that my game engine can read it in and initialize all the map information. The engine reads in the header structure that is first output to the map file ala: ofstream out(szMapName, ios::out); out.write(reinterpret_cast (&Header_t), sizeof(MapHeaderStruct)); Next, a series of structures are written to the file for every map coordinate like so: for(i; i < iNumGrids; i++) { if(i % iMapSizeX == 0 && i != 0) ++iYCount; pgs_t = new GridStruct; pgs_t->iPosX = (i % iMapSizeX); pgs_t->iPosY = iYCount; pgs_t->iNumTiles = 1; //ADD TO THIS LATER pgs_t->iTileIndex[0] = 1; // pgs_t->iTileIndex[1] = 0; // pgs_t->iTileIndex[2] = 0; // out.write(reinterpret_cast (&pgs_t), sizeof(GridStruct)); delete pgs_t; } out.close(); Now this file is read in by the engine, which reads in the header struct just fine (you can read the map name, but it still only shows the first letter if you expand the string view), but when it starts the loop to read in the GridStruct''s, the int''s are initialized to a wacky 351032 or some such. I assume that the file is not offseting properly, but I have no idea at this point. I built in some file position checking (not included in the above), but that didnt help... it looks like everything is working like it should until the grids are read in. So, after all that, could those wierd strings be causing my problems? Im all out of other ideas so please share some of yours! Thx
There is no spoon.
A character array without an ending ''\0'' is not a string. Using strcpy(), srtlen(), etc. can have unpredictable results. Don''t do it.

Mike Roberts
aka milo
mlbobs@telocity.com
Advertisement
What milo said. Use memcpy instead.
Ok then, so how can I make the char* into a string? When I pass in [char*] szName and [int] iSize, and then [char*] szMapName = new char[iSize] it all, I want it to be treated like a string. I''ve tried to assign a null char to then end of the "wannabe string", but then I get debug errors when I try to run the program. Is there a better way to go about this??
There is no spoon.
Hiya,

Yes, it can...has happened to me on many occassions actually

Now, I may not fully get what you''re trying to do here...but if you just want to pass the string across to the SetMapName function, why not just do this:

/***********START OF CODE****************/
// globals
char szMapName[31]="\0";

int main(void)
{
SetMapName("test1.fil");
PrintMapName();
}

// get the passed string and sprintf it to the global
void setMapName(char* szName)
{
sprintf(szMapName,"%s\0",szName);
}

// just print out the global
void PrintMapName(void)
{
printf("<%s>", szMapName); // should print out
}
/***********END OF CODE***********************/

Hopefully I''m in the ballpark. If not, sorry!

-Krylar
You need to make your char array size+1, so you have room for the null.

eg.

void setMapName(char* szName, int iSize)
{
szMapName = new char[iSize + 1];
memcpy(szMapName,szName,iSize);
szMapName[iSize] = 0;
}
Advertisement
Third time trying to get this to post so forgive me if more than one shows up.

A itsy bitsy demo program.

Only the first character of the array when you click ''+'' in the debugger. It would be nice if it showed the whole array since this is what every other debugger I''ve used does. Go Microsquish!

#include int main(int argc, char *argv[]){   int  strSize = 10;   char *strPtr;   strPtr = new char[strSize + 1];   memcpy(strPtr, "THIS WORKS", strSize);   strPtr[strSize] = ''\0'';   printf("%s\n", strPtr);   return(0);} 


Hope that helped.

Mike Roberts
aka milo
mlbobs@telocity.com
Unfortunatly, that wont work with my current framework... All I want to know from people is how they are passing arrays of chars, strings or not, to functions, reading them in from files, whatever! Any time you have to use new to allocate some memory for a string... How should this be done so that you dont end up with those silly "strings" that only show the first char in the debugger when you expand them??

I dont think there should be anything wrong with:

void setName(char* name, int size)
{
char* first;
first = new char[size];
strcpy(name, first);
first[size - 1] = ''\0''; //doing this will piss your compiler off badly!!
}

Maybe Im just a wishful thinker... if you can prove me wrong or show me a better way of doing things, I will be a very happy guy!
There is no spoon.
The debugger is showing you what it thinks you want. You indicated that the szMapName is a pointer to char. It is showing you that char. It doesn''t realize that you want the whole string. You can''t really expand it because it might (in the debugger''s eyes) be infinite. If your string isn''t terminated, you would want to look at szMapName[0], szMapName[1],..., szMapName[n]. This should force the debugger to show the whole string, although it would only be one character per line.
The strcpy function will copy over the full string, including the terminating zero. But, strcpy is used for ansi style strings (8 bit) only. You can use wcscpy for UNICODE style strings (16 bit). But, if you want to use an un-terminated string, you should use strncpy(dest, source, size). This way, the string copy will end at either the terminating zero, or the specified number of characters have been copied, whichever comes first.

-MartinJ
btw, the format of a string is
"blah\0" (read: using text[size-1] = '\0' like in the last post was incorrect)

solution 1 (easiest):
void SetName(char *text)//int leng isn't needed if text is already 0 terminated
{
sprintf(name, text);
}

solution 2 (using char by char- most understandable):
void SetName(char *text)
{
for( int i = 0; i < strlen(text); i++){
name = text;<br>}<br>name = 0;<br>}<br><br>solution 3 (using strcpy):<br>void SetName(char *text)<br>{<br>strcpy(name, text);<br>name[strlen(text)] = 0;<br>} <br> </i> <br><br>Edited by - iwasbiggs on June 6, 2000 9:15:40 PM
___________________________Freeware development:ruinedsoft.com

This topic is closed to new replies.

Advertisement