Sign in to follow this  
Phex

fscanf oddness

Recommended Posts

Phex    140
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

Share this post


Link to post
Share on other sites
doynax    850
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)?

Share this post


Link to post
Share on other sites
Sandman    2210
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) );

Share this post


Link to post
Share on other sites
Phex    140
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 Elements
bool 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; //Friend
public:
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]

Share this post


Link to post
Share on other sites
Sandman    2210
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this