Two questions about a program in C

E

Eoghan

Hi there! I have two simple questions about a program i'm doing:
1) if I write:
enum logic {VERO=1, FALSO=0};
logic trovato=VERO;

Is this correct according to the ANSI '89 standard?

2) I have these lines:
void GetInfo(void)
{
int i=0;
char Dato[256];
printf("Inserire i dati numero %i: ", ++i);
scanf("%[^\n]", Dato);
fflush(stdin);

while( strcmp(Dato, "FINE") )
{
Riempi_Info(Dato); //Fills an array called Estremi
printf("Sigla: %s \t Inizio: %f \tFine: %f\n", Sigle[Nstr],
Estremi[Nstr][0], Estremi[Nstr][1] );
i++;
Nstr++;
printf("Inserire i dati numero %i: ", i);
scanf("%[^\n]", Dato);
fflush(stdin);
}
return;
}

Why does the program crash if I don't call the function fflush after
each scanf? And why in windows can't I use the function fpurge instead?
 
D

Dave Hansen

Hi there! I have two simple questions about a program i'm doing:
1) if I write:
enum logic {VERO=1, FALSO=0};
logic trovato=VERO;

Is this correct according to the ANSI '89 standard?

No. This isn't C++. You need to either add

typedef enum logic logic;

before the definition, or change the definition to

enum logic trovato=VERO;
2) I have these lines: [...]
scanf("%[^\n]", Dato);
fflush(stdin); [...]

Why does the program crash if I don't call the function fflush after
each scanf? And why in windows can't I use the function fpurge instead?

Don't do that. http://c-faq.com/stdio/stdinflush.html

Regards,

-=Dave
 
E

Eric Sosman

Eoghan said:
Hi there! I have two simple questions about a program i'm doing:
1) if I write:
enum logic {VERO=1, FALSO=0};
logic trovato=VERO;

Is this correct according to the ANSI '89 standard?

No. Change `logic' to `enum logic' and it will be correct.
2) I have these lines:
void GetInfo(void)
{
int i=0;
char Dato[256];
printf("Inserire i dati numero %i: ", ++i);
scanf("%[^\n]", Dato);
fflush(stdin);

while( strcmp(Dato, "FINE") )
{
Riempi_Info(Dato); //Fills an array called Estremi
printf("Sigla: %s \t Inizio: %f \tFine: %f\n", Sigle[Nstr],
Estremi[Nstr][0], Estremi[Nstr][1] );
i++;
Nstr++;
printf("Inserire i dati numero %i: ", i);
scanf("%[^\n]", Dato);
fflush(stdin);
}
return;
}

Why does the program crash if I don't call the function fflush after
each scanf?

Probably because of something in Riempi_Info, or in the
declarations of Estremi, Sigle, and Nstr. Unfortunately, you
have not shown any of these, so we cannot tell.

fflush(stdin) invokes undefined behavior. Perhaps the
error of fflush(stdin) somehow cancels out the other error(s).
And why in windows can't I use the function fpurge instead?

There is no fpurge() function in the Standard C library.
If it's a Windows thing, ask about it in a Windows forum.
 
W

Walter Roberson

Eoghan said:
2) I have these lines:
void GetInfo(void)
{
int i=0;
char Dato[256];
printf("Inserire i dati numero %i: ", ++i);
scanf("%[^\n]", Dato);

Output is not certain to appear before the next input
(especially when the output does not end in '\n') unless
the output stream is fflush()'d.

You did not put a size constraint on the scanf(), so if the
user enters more characters than you have alloted (255) then
your program will have undefined behaviour.
fflush(stdin);

fflush() is only defined for output and update streams.
 
B

Ben Bacarisse

Eoghan said:
Hi there! I have two simple questions about a program i'm doing:
1) if I write:
enum logic {VERO=1, FALSO=0};
logic trovato=VERO;

Is this correct according to the ANSI '89 standard?

No, you need to say: 'enum logic trovato = VERO;' and if you are not
getting a diagnostic from your version you should review what compiler
options you are using.
2) I have these lines:
void GetInfo(void)
{
int i=0;
char Dato[256];
printf("Inserire i dati numero %i: ", ++i);
scanf("%[^\n]", Dato);
fflush(stdin);

You simply are not allowed to do this in a portable program. Your
system is allowed to define some meaning for this code, but it means
nothing in standard C. fflush is for output streams.

To replace this, write a look that skips to EOF or newline (as a
function, of course!). Maybe:

int c;
do {
c = getc(stdin);
} while (c != EOF && c != '\n');
while( strcmp(Dato, "FINE") )
{
Riempi_Info(Dato); //Fills an array called Estremi
printf("Sigla: %s \t Inizio: %f \tFine: %f\n", Sigle[Nstr],
Estremi[Nstr][0], Estremi[Nstr][1] );
i++;
Nstr++;
printf("Inserire i dati numero %i: ", i);
scanf("%[^\n]", Dato);
fflush(stdin);
}
return;
}

Why does the program crash if I don't call the function fflush after
each scanf?

My guess is that problem is be caused by other parts of your program
(not shown) doing something wrong when the scanf reads an empty
string.
And why in windows can't I use the function fpurge instead?

Why would you want to? Stick to standard C and your program will run
almost anywhere.
 
E

Eoghan

On the web fpurge is said to be included in stdio.h

I'm sure the string has less than 256 characters, however here's the
code of RiempiInfo:
void Riempi_Info(char* str)
{
int k=0;

while(str[k]!=' ' && str[k]!='\0') Sigle[Nstr][k]=str[k++];

str=strchr(str, (int)' ');
Estremi[Nstr][0]=atof(&str[1]);

/*Parto da str[1] perche' str[0] e' gia uno spazio*/
str=strchr(&str[1], (int)' ');
Estremi[Nstr][1]=atof(&str[1]);
return;
}

where the variables are:
char Sigle[256][10]; (I'm way sure Nstr is less than 256)
float Estremi[100][2];
 
E

Eoghan

If I don't use fflush the program behaves liek this:

Inserire i dati numero 1:

I write:One 0.0 0.3 and I press return

Then the programs writes:

Sigla: ewf Inizio: 0.000000 Fine: 0.300000
Inserire i dati numero 2: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
Inserire i dati numero 3: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
Inserire i dati numero 4: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
Inserire i dati numero 5: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
Inserire i dati numero 6: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
Inserire i dati numero 7: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
Inserire i dati numero 8: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
Inserire i dati numero 9: Sigla: ewf Inizio: 0.000000 Fine:
0.300000
.....
and so on
 
E

Eric Sosman

Eoghan said:
On the web fpurge is said to be included in stdio.h

I'm sure the string has less than 256 characters, however here's the
code of RiempiInfo:
void Riempi_Info(char* str)
{
int k=0;

while(str[k]!=' ' && str[k]!='\0') Sigle[Nstr][k]=str[k++];

str=strchr(str, (int)' ');
Estremi[Nstr][0]=atof(&str[1]);

And if strchr() returned NULL ...?

Note that strchr() *will* return NULL (see code in
original post) if you don't do something to get rid of
the '\n' that stopped the scanf() -- because the next
scanf() will stop on the same '\n', and the buffer will
then hold a '\0' in its first position.

It seems likely that fflush(stdin), whose behavior
is undefined by C, may have the effect of swallowing the
'\n' *on your system* and *under today's circumstances*,
which is why inserting fflush(stdin) fixes your problem.
But that's not a "fix," it's a "kludge."

See Questions 12.26a and 12.26b in the comp.lang.c
Frequently Asked Questions (FAQ) list, http://www.c-faq.com/.
 
D

Default User

Eoghan said:
On the web fpurge is said to be included in stdio.h

It is not a standard C function. Whether or not some implementation
includes a declaration in a standard header doesn't change that.



Brian
 
E

Eoghan

Well, as some of you said, I left my computer for 5 minutes, I
executed the program again and fflush didn't work anymore!

But I think I solved the problem. Because I used this version of
scanf: scanf("%[^\n]", Dato), the \n character was never read. So
using the function proposed by Ben Bacarisse, everything seems to be
allright.
Do you think that this way to use scanf could have been the problem?

Anyway, abaout the use of enum logic:
I buill the source with VC6 and XCode but I didn't have problems. I
had problems with and older version of XCode. However, you have said
that the enumerations are included in ansi '89 standard of C++, but
also in the ansi '89 of C?
 
W

Walter Roberson

However, you have said
that the enumerations are included in ansi '89 standard of C++, but
also in the ansi '89 of C?

No, the first C++ standard was 1998, not 1989.

The 1989 ANSI C standard describes enumerations in sections
3.1.2.5, 3.5.2.2, and 3.5.2.3.
 
B

Ben Bacarisse

Eoghan said:
But I think I solved the problem. Because I used this version of
scanf: scanf("%[^\n]", Dato), the \n character was never read. So
using the function proposed by Ben Bacarisse, everything seems to be
allright.
Do you think that this way to use scanf could have been the problem?

Yes. I think about three (maybe more!) people have posted remarks to
say that not reading past the newline character is the root of the
problem.
Anyway, abaout the use of enum logic:
I buill the source with VC6 and XCode but I didn't have problems. I
had problems with and older version of XCode. However, you have said
that the enumerations are included in ansi '89 standard of C++, but
also in the ansi '89 of C?

You have to decide if you want C or C++ code. All versions of both
language standards have enumerations, but in C++ you can omit the
"enum" keyword because the enumeration tag acts as a type name. In C
it does not (and that applies to all versions of the language
standard).
 
P

pete

Eoghan said:
Hi there! I have two simple questions about a program i'm doing:
1) if I write:
enum logic {VERO=1, FALSO=0};
Is this correct according to the ANSI '89 standard?

That line is correct, but I think that
any of these ways to write it, would be better:

enum logic {FALSO = 0, VERO};

enum logic {FALSO, VERO};

enum logic {FALSO = 0, VERO = 1};
 
J

Jack Klein

E

Eric Sosman

pete said:
That line is correct, but I think that
any of these ways to write it, would be better:

enum logic {FALSO = 0, VERO};

enum logic {FALSO, VERO};

enum logic {FALSO = 0, VERO = 1};

... but don't make this mistake, which a colleague
of mine once uncovered in somebody's actual code:

typedef enum { TRUE, FALSE } Boolean;
 
R

Ralf Damaschke

Eoghan said:
while(str[k]!=' ' && str[k]!='\0') Sigle[Nstr][k]=str[k++];

Here is another problem: in the assignment statement k is
modified and its prior value is also used (for other purpose
than to determine the value [of k] to be stored): that causes
undefined behavior and whatever happens - it may well be not
what you wanted.

Ralf
 

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,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top