Thread: file saving: trouble with strings and strncpy()

  1. #1
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071

    file saving: trouble with strings and strncpy()

    Iv'e written a function to save some strings and floats (function parameters to be loaded later) to simple ASCII file. The variables are written to the file, based on data in an array, accessed with a for loop.
    To write the strings, i'm using strncpy to copy the values into temporary variables, so I can keep everything at a consistant size.
    However, when it saves, it saves so that the the string variables don't seem to change..tmptex0 writes the same thing over and over.

    Code:
    void level::save(char *fname)
    {
    	stream = fopen(fname, "w+");
    	fseek(stream, 0L, SEEK_SET);
    
    	fprintf(stream, "%ld\n", VERSION);
    
    	//prefabs
    	fprintf(stream, "%d\n", num_prefabs);
    	for(int i=0; i<num_prefabs; i++)
    	{
    		strncpy(tmptex0, prefabP[i].strtexture0, sizeof(GLUI_String));
    		strncpy(tmptex1, prefabP[i].strtexture1, sizeof(GLUI_String));
    		if(prefabP[i].type==0)
    			fprintf(stream, "%ld %s %s %d %f %f %f %f %f %f\n", SOLIDCUBE, 
    			tmptex0, tmptex1, prefabP[i].textype, 
    			prefabP[i].pos.x, prefabP[i].pos.y, prefabP[i].pos.z, 
    			prefabP[i].scale.x, prefabP[i].scale.z, prefabP[i].scale.y);
    	}
    
    	//entities
    	fprintf(stream, "%d\n", num_meshs);
    	for(i=0; i<num_meshs; i++)
    	{
    		strncpy(tmptex0, meshP[i].tex1, sizeof(GLUI_String));
    		strncpy(tmptex1, meshP[i].tex2, sizeof(GLUI_String));
    		strncpy(tmpfname, meshP[i].filename, sizeof(GLUI_String));
    		fprintf(stream, "%ld %s %s %s %d %f %f %f %f %f %f\n", STATICMESH, 
    			tmpfname, tmptex0, tmptex1, meshP[i].textype, 
    			meshP[i].pos.x, meshP[i].pos.y, meshP[i].pos.z, 
    			meshP[i].scale.x, meshP[i].scale.z, meshP[i].scale.y);
    	}
    	
    	fclose(stream);
    }
    Anyway, the question is, what's the problem here, and how can it be solved?

    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  2. #2
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    > strncpy(tmptex0, prefabP[i].strtexture0, sizeof(GLUI_String));
    Here you probably want:
    Code:
    strncpy(tmptex0, prefabP[i].strtexture0, strlen(GLUI_String));
    And you may need to add a string terminator:
    Code:
    tmptex0[strlen(GLUI_String)] = '\0';

  3. #3
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    nope, that didn't do anything

    GLUI_String is a type, so it has to use sizeof() (same as you would use sizeof(float) or sizeof(int)).

    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    1) How are tmptex0 and tmptex0 declared?
    2) What happens if you print prefabP[i].strtexture0, prefabP[i].strtexture1, meshP[i].tex1, and meshP[i].tex2 directly instead of copying them to a temporary first?

    Also, you may want to print sizeof(GLUI_String) is to be sure it's what you expect.

  5. #5
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    declarations:
    Code:
    char tmptex0[sizeof(GLUI_String)]={0};
    char tmptex1[sizeof(GLUI_String)]={0};
    These strings are taken in from text-boxs that write to strings that HAVE to be >=GLUI_String. The strncpy makes sure that all the file name strings being read and written are >=GLUI_String.
    (^not sure if thats explained clearly enough, but thats the best I can do^)

    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  6. #6
    Registered User
    Join Date
    Aug 2005
    Posts
    1,267
    how is GLUI_String declared? using sizeof operator on it may or may not work.

  7. #7
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    from glui.h (I didn't write this!):
    Code:
    class GLUI_String
    {
    public:
      char string[300];
    
      char &operator[]( int i ) {
        return string[i];
      }
    
      operator char*() { return (char*) &string[0]; };
      /*    operator void*() { return (void*) &string[0]; }; */
    
      GLUI_String( void ) {
        string[0] = '\0';
      }
    
      GLUI_String( char *text ) {
        strcpy( string, text );
      }
    };
    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  8. #8
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    well, iv'e changed it to not use GLUI_String at all, and it still does the same thing!?
    Code:
    void level::save(char *fname)
    {
    	stream = fopen(fname, "w+");
    	fseek(stream, 0L, SEEK_SET);
    
    	fprintf(stream, "%ld\n", VERSION);
    
    	//prefabs
    	fprintf(stream, "%d\n", num_prefabs);
    	for(int i=0; i<num_prefabs; i++)
    	{
    		if(prefabP[i].type==0)
    			fprintf(stream, "%ld %s %s %d %f %f %f %f %f %f\n", SOLIDCUBE, 
    			prefabP[i].strtexture0, prefabP[i].strtexture1, prefabP[i].textype, 
    			prefabP[i].pos.x, prefabP[i].pos.y, prefabP[i].pos.z, 
    			prefabP[i].scale.x, prefabP[i].scale.z, prefabP[i].scale.y);
    	}
    
    	//entities
    	fprintf(stream, "%d\n", num_meshs);
    	for(int j=0; j<num_meshs; j++)
    	{
    		fprintf(stream, "%ld %s %s %s %d %f %f %f %f %f %f\n", STATICMESH, 
    			meshP[j].filename, meshP[j].tex1, meshP[j].tex2, meshP[j].textype, 
    			meshP[j].pos.x, meshP[j].pos.y, meshP[j].pos.z, 
    			meshP[j].scale.x, meshP[j].scale.z, meshP[j].scale.y);
    	}
    	
    	fclose(stream);
    }
    I'm now completely lost with this :s

    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Well, assuming prefabP[i].strtexture0, prefabP[i].strtexture1, meshP[i].tex1, and meshP[i].tex2 are all char arrays, that pretty much indicates the problem is elsewhere, if each array element is printing out the same string.

  10. #10
    The Right Honourable psychopath's Avatar
    Join Date
    Mar 2004
    Location
    Where circles begin.
    Posts
    1,071
    Those variables arn't arrays..so what does that mean?:
    Code:
    	char *strtexture0;
    	char *strtexture1;
    Code:
    	char *filename;
    	char *tex1; 
    	char *tex2;
    -psychopath
    M.Eng Computer Engineering Candidate
    B.Sc Computer Science

    Robotics and graphics enthusiast.

  11. #11
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >Those variables arn't arrays..so what does that mean?:
    Well those are just pointers to char, so unless you allocate some memory for them, you can't copy char strings into them, you can only assign other char pointers to them.

    So if you're trying to store strings in them, you need to use new to allocate some memory for them, or make them strings or char arrays.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM