fscanf hangs

P

PeterOut

I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2).

I am not sure if this is a C, C++ or MS issue but fscanf has been
randomly hanging on me. I make the call hundreds, if not thousands,
of times but it hangs in different places with the same data. The
offending code follows.

ReadFile(char *csFileName)
{
float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1;
int iRead;
FILE *fpInFile;

if ((fpInFile= fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

do
{
// It randomly hangs on the followinf
line
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);
if (iRead==0 || iRead==EOF) break;
} while (lX < lLastX || lY < lLastY);
}

I am wondering if I should just do binary reading so as to have more
control over what is going on.

Many thanks in advance for any assistance,
Peter.
 
A

Amal P

I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2).

I am not sure if this is a C, C++ or MS issue but fscanf has been
randomly hanging on me. I make the call hundreds, if not thousands,
of times but it hangs in different places with the same data. The
offending code follows.

ReadFile(char *csFileName)
{
float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1;
int iRead;
FILE *fpInFile;

if ((fpInFile= fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

do
{
// It randomly hangs on the followinf
line
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);
if (iRead==0 || iRead==EOF) break;
} while (lX < lLastX || lY < lLastY);

}

I am wondering if I should just do binary reading so as to have more
control over what is going on.

Many thanks in advance for any assistance,
Peter.

Dear Peter,

Your are not closing the file.
Use fclose for closing the file.

Thanks and regards,
Amal P.
 
P

PeterOut

Dear Peter,

Your are not closing the file.
Use fclose for closing the file.

Thanks and regards,
Amal P.- Hide quoted text -

- Show quoted text -

Sorry. I am closing the file with
fclose(fpInFile);
but forgot to include that in the sample code that I posted. The
problem, unfotruntately, lies elsewhere.

Thanks,
Peter.
 
M

Mike Wahler

PeterOut said:
I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2).

I am not sure if this is a C, C++ or MS issue but fscanf has been
randomly hanging on me. I make the call hundreds, if not thousands,
of times but it hangs in different places with the same data. The
offending code follows.

ReadFile(char *csFileName)
{
float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1;
int iRead;
FILE *fpInFile;

if ((fpInFile= fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

do
{
// It randomly hangs on the followinf
line
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);

%d is for type 'int'. For type 'long', use %ld.

Also make sure you've #included <stdio.h> for the
declaration of 'fscanf()'.

-Mike
 
B

Barry Schwarz

I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2).

You posted to numerous inconsistent newsgroups. Are you coding in C
or C++? What do you think this has to do with Microsoft Foundation
Classes?
I am not sure if this is a C, C++ or MS issue but fscanf has been
randomly hanging on me. I make the call hundreds, if not thousands,
of times but it hangs in different places with the same data. The
offending code follows.

ReadFile(char *csFileName)
{
float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1;
int iRead;
FILE *fpInFile;

if ((fpInFile= fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

do
{
// It randomly hangs on the followinf
line

How do you determine that?
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);
if (iRead==0 || iRead==EOF) break;

You really should check that fscanf did everything you asked and iRead
is in fact 5. If 0<=iRead<5, there is something wrong with the data
in your file.
} while (lX < lLastX || lY < lLastY);
}

I am wondering if I should just do binary reading so as to have more
control over what is going on.


Remove del for email
 
M

Martin Ambuhl

PeterOut said:
I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2).

I am not sure if this is a C, C++ or MS issue

from the variable names, it looks like a Transylvanian Heresy problem,
but...
but fscanf has been
randomly hanging on me.

Because you use the wrong specifiers to fscanf

[...]
float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1; [...]
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);

"%d" is the specifier for an int, but lLong1, lLong2, and lNum are not
ints. If you are going to clutter your code with those god-awful names
that carry their types with them, I would think you would learn basic
stuff like this.
 
J

James Kanze

I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2).
I am not sure if this is a C, C++ or MS issue but fscanf has been
randomly hanging on me. I make the call hundreds, if not thousands,
of times but it hangs in different places with the same data. The
offending code follows.

The code would be a lot easier to understand (and a lot safer)
if you'd use ifstream instead of fscanf. However...
ReadFile(char *csFileName)
{
float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1;
int iRead;
FILE *fpInFile;
if ((fpInFile= fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

do
{
// It randomly hangs on the followinf
line
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);

As others have pointed out, you need %ld to be correct. If this
doesn't cause problems immediately, it's because by pure chance,
longs and ints have the same size on your implementation.
if (iRead==0 || iRead==EOF) break;

And what is fscanf supposed to return in the case of:
"1 2 3x 4.5 6"
?

Personally, I'd probably impose that each data set be on a
separate line, and do something like:

std::string line ;
int lineNo = 0 ;
while ( std::getline( input, line ) ) {
++ lineNo ;
std::istringstream s( line ) ;
s >> long1 >> long2 >> float1 >> float2 >> num >> std::ws ;
if ( ! s || s.get() != EOF ) {
std::cerr << "Syntax error in line "
<< lineNo
<< ", ignoring it"
<< std::endl ;
} else {
// ...
}
}
From your code, it's also not too clear where the lX and lY come
from, or how they evolve to handle your end conditions.
Normally, written correctly, using std::vector, you should be
able to automatically scale any arrays to the amount of data
read.
} while (lX < lLastX || lY < lLastY);
}
I am wondering if I should just do binary reading so as to have more
control over what is going on.

How would that change anything?
 
C

CBFalconer

Martin said:
.... snip ...

"%d" is the specifier for an int, but lLong1, lLong2, and lNum
are not ints. If you are going to clutter your code with those
god-awful names that carry their types with them, I would think
you would learn basic stuff like this.

That seems like fairly accurate straight forward advice :)
 
P

PeterOut

%d is for type 'int'. For type 'long', use %ld.

Also make sure you've #included <stdio.h> for the
declaration of 'fscanf()'.

-Mike- Hide quoted text -

- Show quoted text -

Thanks very much for your help.
I had #included <stdio.h> but changed the %d to $ld and have not had a
problem since. I was surprised that it made a difference on 32-bit
Windows since I thought int and long were both 32 bits on 32-bit
Windows. I think they are different on Unix and Linux where I think
it is 32 bits for int and 64 bits for long but I may be wrong.
Thanks again,
Peter.
 
P

PeterOut

from the variable names, it looks like a Transylvanian Heresy problem,

The original variable names were application specific althought they
included the Hungarian notation that everyone seems to like so much ;)
but...
but fscanf has been
randomly hanging on me.

Because you use the wrong specifiers to fscanf

[...]


float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1; [...]
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);

"%d" is the specifier for an int, but lLong1, lLong2, and lNum are not
ints. If you are going to clutter your code with those god-awful names
that carry their types with them, I would think you would learn basic
stuff like this.

Mike had pointed that out and I have not had any problems since I
fixed it. However, it had been runing w/o problems beforehand and
then started playing up and hagning there for some reason.

Thanks,
Peter.
 
P

PeterOut

The code would be a lot easier to understand (and a lot safer)
if you'd use ifstream instead of fscanf. However...

Thanks. The code appears to be woking OK now that I have fixed the %d/
%ld problem but will certainly look into that if fscanf gives me any
more problems.
As others have pointed out, you need %ld to be correct. If this
doesn't cause problems immediately, it's because by pure chance,
longs and ints have the same size on your implementation.


And what is fscanf supposed to return in the case of:
"1 2 3x 4.5 6"
?

Personally, I'd probably impose that each data set be on a
separate line, and do something like:

std::string line ;
int lineNo = 0 ;
while ( std::getline( input, line ) ) {
++ lineNo ;
std::istringstream s( line ) ;
s >> long1 >> long2 >> float1 >> float2 >> num >> std::ws ;
if ( ! s || s.get() != EOF ) {
std::cerr << "Syntax error in line "
<< lineNo
<< ", ignoring it"
<< std::endl ;
} else {
// ...
}
}

Yes. Being able to split things up would probably make it easier to
diagnose the problem.
from, or how they evolve to handle your end conditions.
Normally, written correctly, using std::vector, you should be
able to automatically scale any arrays to the amount of data
read.


How would that change anything?

I thought that it might make the problems more transparent. fscanf
did not return an error. It just hung ad infinitum. Something
binary, I could just read the bytes and it would not really matter
about formatting. I could read everythings in as a character string
and then analyze it rather than relying upon however fscanf, or
whatever, was written.

Thanks again for your help,
Peter.
 
J

Johan Bengtsson

PeterOut said:
The original variable names were application specific althought they
included the Hungarian notation that everyone seems to like so much ;)
Not me
 
P

PeterOut

%d is for type 'int'. For type 'long', use %ld.

Also make sure you've #included <stdio.h> for the
declaration of 'fscanf()'.

-Mike- Hide quoted text -

- Show quoted text -

Unfortunately, the problem has started happening again, even with %ld
and #include <stdio.h>. I wonder if it's a problem with MS Visual C+
+. It seems to be correlated with my "breaking" during operation
although it is not clear whther that is a cause or an effect.

Thanks,
Peter.
 
K

Keith Thompson

[offending code snipped]
Unfortunately, the problem has started happening again, even with %ld
and #include <stdio.h>. I wonder if it's a problem with MS Visual C+
+. It seems to be correlated with my "breaking" during operation
although it is not clear whther that is a cause or an effect.

If you'll post your current code, along with a detailed description of
how it's failing, we can probably help. We can't guess what your code
actually looks like now. In the meantime, read section 12 of the
comp.lang.c FAQ, <http://www.c-faq.com/>; it's entirely possible that
you'll find the solution there.

I've dropped comp.lang.c++ and comp.os.ms-windows.programmer.tools.misc
from the newsgroups line.
 
B

Barry Schwarz

On Fri, 22 Jun 2007 07:55:45 -0700, PeterOut


snip obsolete code
Unfortunately, the problem has started happening again, even with %ld
and #include <stdio.h>. I wonder if it's a problem with MS Visual C+
+. It seems to be correlated with my "breaking" during operation
although it is not clear whther that is a cause or an effect.
If you don't post your current code, no one will be able to help you.
If you keep posting to irrelevant groups, no one will want to help
you.


Remove del for email
 
P

PeterOut

[offending code snipped]
Unfortunately, the problem has started happening again, even with %ld
and #include <stdio.h>. I wonder if it's a problem with MS Visual C+
+. It seems to be correlated with my "breaking" during operation
although it is not clear whther that is a cause or an effect.

If you'll post your current code, along with a detailed description of
how it's failing, we can probably help. We can't guess what your code
actually looks like now. In the meantime, read section 12 of the
comp.lang.c FAQ, <http://www.c-faq.com/>; it's entirely possible that
you'll find the solution there.

Sorry about that. Herewith is the updated code.

------------------------------------------------------------

if ((fpFile = fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

{
float fMean, fSD;
long lX, lY, lNumItems, lLastX = fppPlane->iColumns-1, lLastY =
fppPlane->iRows-1;
int iRead;

do
{
iRead=fscanf(fpFile, "%ld%ld%f%f%ld", &lX, &lY, &fMean, &fSD,
&lNumItems);
if (iRead==0 || iRead==EOF) break;
fppPlane->Data[lY][lX] = fMean;
} while (lX < lLastX || lY < lLastY);
}

fclose(fpFile);

------------------------------------------------------------

Usually there is no problem but sometimes it hangs on
iRead=fscanf(fpFile, "%ld%ld%f%f%ld", &lX, &lY, &fMean, &fSD,
&lNumItems);

When it does not, iRead==5.

Thanks,
Peter.
 
K

Keith Thompson

PeterOut said:
If you'll post your current code, along with a detailed description of
how it's failing, we can probably help. We can't guess what your code
actually looks like now. In the meantime, read section 12 of the
comp.lang.c FAQ, <http://www.c-faq.com/>; it's entirely possible that
you'll find the solution there.

Sorry about that. Herewith is the updated code.

------------------------------------------------------------

if ((fpFile = fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

{
float fMean, fSD;
long lX, lY, lNumItems, lLastX = fppPlane->iColumns-1, lLastY =
fppPlane->iRows-1;
int iRead;

do
{
iRead=fscanf(fpFile, "%ld%ld%f%f%ld", &lX, &lY, &fMean, &fSD,
&lNumItems);
if (iRead==0 || iRead==EOF) break;
fppPlane->Data[lY][lX] = fMean;
} while (lX < lLastX || lY < lLastY);
}

fclose(fpFile);

------------------------------------------------------------

Usually there is no problem but sometimes it hangs on
iRead=fscanf(fpFile, "%ld%ld%f%f%ld", &lX, &lY, &fMean, &fSD,
&lNumItems);

When it does not, iRead==5.

It's still hard to tell what's going on, because you haven't shown us
a complete program. I see no main function, and no declarations
for fpFile, csFileName, ErrorOpeningFile, etc.

You also haven't given us any clue about what information is in the
file you're attempting to read.

Remember that fscanf with any of the numeric formats, including "%ld"
and "%f", will skip over any leading whitespace before reading a
number; whitespace can include newline characters. Are you attempting
to read from a disk file? Could it be that you're expecting a certain
layout for each input line, and the actual input you're seeing doesn't
match your expectation? I wouldn't expect fscanf to "hang" unless
it's reading from an interactive device, but it's something to think
about.

Also, fscanf invokes undefined behavior if the input value overflows
the target type. For example, if you attempt to read the string
"1.0e1000000" with a "%f" format, *anything* could happen.

Take the code you just posted and modify it into *small* *complete*
program that exhibits the problem. Here's a suggestion; tweak to
taste:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
FILE *fpFile;
const char *csFileName = "input.txt"; /* or whatever */

if ((fpFile = fopen(csFileName, "r")) == NULL) {
fprintf(stderr, "fopen failed for %s\n", csFileName);
exit(EXIT_FAILURE);
}

{
int iRead;
long input1, input2;
float input3, input4;
long input5;

while (1) {
iRead=fscanf(fpFile,
"%ld%ld%f%f%ld",
&input1, &input2, &input3, &input4, &input5);
printf("%d: %ld %ld %g %g %ld\n",
iRead, input1, input2, input3, input4, input5);
if (iRead < 5) {
break;
}
}
}
fclose(fpFile);
exit(EXIT_SUCCESS);
}

Note that this just reads input items; it doesn't know or care what
they mean or how they fit into your other data structures.

If you can reproduce the same problem with this program, or with
something similar, then post again -- and tell us exactly what the
input file looks like. (In fact, trim the input file itself down to
the minimum necessary to reproduce the problem.) If you can do this,
you're likely to figure out the problem for yourself before you get
around to posting.
 
B

Barry Schwarz

Sorry about that. Herewith is the updated code.

------------------------------------------------------------

if ((fpFile = fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

{
float fMean, fSD;
long lX, lY, lNumItems, lLastX = fppPlane->iColumns-1, lLastY =
fppPlane->iRows-1;
int iRead;

do
{
iRead=fscanf(fpFile, "%ld%ld%f%f%ld", &lX, &lY, &fMean, &fSD,
&lNumItems);
if (iRead==0 || iRead==EOF) break;

What you want here is
if (iRead != 5){Some very thorough debugging output. Printout
iRead and all five objects that should have been updated. You can end
with a break if you like but give yourself a fighting chance to see
where the error is.}
fppPlane->Data[lY][lX] = fMean;

At this point, you might want to include some output just so you can
see the program progress through the file.
} while (lX < lLastX || lY < lLastY);

This implies it is possible for lX to exceed lLastX. If it exceeds
the limit by more than one you will have invoked undefined behavior in
the previous assignment statement. Ditto for lY. It also means you
stop processing after the first value is stored in the last row or
last column, probably not what you intended.
}

fclose(fpFile);

------------------------------------------------------------

Usually there is no problem but sometimes it hangs on
iRead=fscanf(fpFile, "%ld%ld%f%f%ld", &lX, &lY, &fMean, &fSD,
&lNumItems);

How do you know this is where it hangs?
When it does not, iRead==5.


Remove del for email
 
J

Johan Bengtsson

PeterOut said:
I am using MS Visual C++ 6.0 on Windows XP 5.1 (SP2).

I am not sure if this is a C, C++ or MS issue but fscanf has been
randomly hanging on me. I make the call hundreds, if not thousands,
of times but it hangs in different places with the same data. The
offending code follows.

ReadFile(char *csFileName)
{
float fFloat1, fFloat2;
long lLong1, lLong2, lNum, lLastX = iColumns-1, lLastY =iRows-1;
int iRead;
FILE *fpInFile;

if ((fpInFile= fopen(csFileName, "r")) == NULL) return
ErrorOpeningFile(csFileName);

do
{
// It randomly hangs on the followinf
line
iRead=fscanf(fpInFile, "%d%d%f%f%d", &lLong1, &lLong2, &fFloat1,
&fFloat2, &lNum);
if (iRead==0 || iRead==EOF) break;
} while (lX < lLastX || lY < lLastY);
}

I am wondering if I should just do binary reading so as to have more
control over what is going on.

Many thanks in advance for any assistance,
Peter.
Hmmm, I was thinking that it might be a consequence of corrupt memory
(like buffer overruns, changing memory after free() (or equivalent) or
some other similar problem).
Test if you have access to a function called AfxCheckMemory(). (It is
available in later versions of their compiler, don't know if it is in
that version however).
If it is available try placing

ASSERT(AfxCheckMemory());

immediately before the call to fscanf(). If it breaks you have
previously overwritten some memory somewhere in your program where that
should not happen...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top