fscanf oddness

Started by
3 comments, last by Sandman 18 years, 11 months ago
I am referring to VC++. Hello, I am experiencing a very strange bug when using fscanf(). I have used it before and it always worked fine for me, but when I now try to read something from an opened file (fopen() returns success!), it does not always give me the expected results. I have a class C with |-----a char string[99]. |-----two integers: int a, int b. Lets assume the file I want to read from is a text file with this content:
Quote: loremipsumdolorsitamet 42 0
My reading code looks like this

FILE *stream = fopen( "file.txt", "r" );	//open file: returns success	(line 1)
fscanf( stream, "%s", C->string );      	//read in String			(line 2)
fscanf( stream, "%d %d", &C->a, &C->b );	//read in Integers			(line 3)
fclose( stream );                     		//close file.				(line 4)








When I observe this part of the code during runtime, C->string is undefined before line 2 and correctly containing "loremipsumdolorsitamet" after line 2. But when line 3 is executed, C->string becomes "", or more exactly "\0\0\0emipsumdolorsitamet", which means the first 3 characters are kind of cut off! But on the other hand the two integers are both assigned correctly. When I simply delete line 3, the string is also working. What makes me really confuse is that somewhere else in my program the same code works perfectly... Does anybody have an idea what I am doing wrong? rgds, Phex
Advertisement
That's odd.. I can't see anything wrong with it.
Any chance you could post the structure definition and allocation too (or preferably a complete example)?
A large part of the problem is that you're using fscanf, which while powerful, is also horribly unsafe. The C++ filestream objects are a bit more secure, it's generally better to use those instead, even if they are a bit more fiddly to use.

Other than that, it looks like some sort of weird memory overwriting problem. Make sure that the object is properly constructed, and it might also be worth enclosing the dereference in brackets to make sure you're pointing fscanf to the right chunk of memory, e.g

fscanf( stream, "%d %d", &(C->a), &(C->b) );
Quote:Original post by doynax
That's odd.. I can't see anything wrong with it.
Any chance you could post the structure definition and allocation too (or preferably a complete example)?


To sum it up, I am using a dynamic template List cList<class T> to collect Elements that contain several data informations including a string and integers.

This is a more specific code example:
1) Element Header file
2) Main source file
3) Dynamic List header (though not really neccessary I think)
// ELEMENT - HEADER FILE //////////////////////////////////////////////////////class cElement{public:	char string[99];	//said string	int a, b;		//said integers	//Dynamic List variables (not really of interest here)	cElement *Next;	//(cElement not cAction, thx Sandman!)	cElement *Prev;	cElement()		//ctor	{ 		Next = Prev = 0; 	}};// MAIN - SOURCE FILE ////////////////////////////////////////////////////////Creating a dynamic List of "Elements"cList<cElement> List;//Read Data into List of Elementsbool Read()	{	//Open File	FILE *read;	if( (read = fopen( "file.txt", "r" )) == 0 )		return false;	//Read in Data	while( !feof( read ) )	{		cElement *NEW;		NEW = List.Add(); //Add new Element to the List, remember address		//Read in Data		fscanf( read, "%s", NEW->string );			(=> string assigned correctly)		fscanf( read, "%d %d", &(NEW->a), &(NEW->b) );	(=> string damaged)	}	//Close File, return success	fclose( read );	return true;}void main(){	//Reading in variables	if( !Read() )		printf( "error" );	else		printf( "%s", List->First->string );		//Now "loremipsumdolorsitamet" should be printed, but instead nothing happens}// DYNAMIC LIST - HEADER FILE ////////////////////////////////////////////////////template <class T>class cList //Objektlist{friend class T;	//Friendpublic:	T *First;	//First Element	T *Last;	//Last Element	T *Add();	//Attach new Element	void Remove(T *&obj); //delete Element	cList()		//ctor	{ 		First = Last = 0;	}};template <class T>T *cList<T>::Add(){	//Go to end of list	T *List = Last;	//Create new Element	List = new T;	// Next, Prev, First & Last	if(Last)	{		Last->Next = List;		List->Prev = Last;		Last = List;	}	else		First = Last = List;	//return new Element	return List;}template <class T>void cList<T>::Remove( T *&obj ){	//Check if valid	if( !obj )		return;	//Assign connections	if( obj->Prev )		obj->Prev->Next = obj->Next;	if( obj->Next )		obj->Next->Prev = obj->Prev;		//finally delete obj	delete obj;	obj = 0;}


When using another List like cList<cItem> another file to read from, everything works fine...

[Edited by - Phex on May 25, 2005 4:13:08 PM]
Quote:Original post by Phex
*** Source Snippet Removed ***


It's probably just a copy/paste error in the posted source, but the Next and Prev pointers, as well as the constructor are for type cAction, not cElement.

This topic is closed to new replies.

Advertisement