Newbie questions

B

Blue Ocean

First off, thank you all for all the help you gave me last time! I
really appreciate it. I have a new question that is kinda OT so I'm
not actually going to ask the question here. The FAQ does not state
what to do if you have a baffling error that you just cannot figure
out, so I'm going to ask here. Is anyone here willing to take a look
at a page long piece of code and help me find the error? It compiles
correctly, and it's so simple that you wouldn't think there could be a
problem, but there is some problem with the scanf() function
somewhere.

If you want to help, just e-mail me at the address above, or post here
and I will e-mail the problem code to you, and it's printout.

If I'm not allowed to ask for specific help here, could someone please
tell me where I should ask for help, or how I should ask for help, and
in which FAQ that question is answered, because I could not find it in
the one for this group.

Thanks again in advance and again to those of you who helped me with
my last question!

James
 
R

Randy Howard

blueoceanz1 said:
Is anyone here willing to take a look
at a page long piece of code and help me find the error? It compiles
correctly, and it's so simple that you wouldn't think there could be a
problem, but there is some problem with the scanf() function somewhere.

A problem with a compilable piece of code using a standard function
shouldn't be OT here. Why not just post the code and see what kind
of help you get?
 
C

CBFalconer

Blue said:
.... snip ...
out, so I'm going to ask here. Is anyone here willing to take a look
at a page long piece of code and help me find the error? It compiles
correctly, and it's so simple that you wouldn't think there could be a
problem, but there is some problem with the scanf() function
somewhere.

If you want to help, just e-mail me at the address above, or post here
and I will e-mail the problem code to you, and it's printout.

If I'm not allowed to ask for specific help here, could someone please
tell me where I should ask for help, or how I should ask for help, and
in which FAQ that question is answered, because I could not find it in
the one for this group.

You *are* allowed to post code and ask for help here. Just make
sure it is not excessively long, is compilable, is standard C, and
indicate clearly what the problem is.
 
B

Blue Ocean

Randy Howard said:
A problem with a compilable piece of code using a standard function
shouldn't be OT here. Why not just post the code and see what kind
of help you get?

I will, thanks. I will also take a look at the links that the others
posted.

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

void addNewNumber(float *pointer);
float getLowest(float array[], int length);

int main()
{
int total;

printf("Numbers to sort: ");
scanf("%d\n", &total);

float array[total];

for(int i = 0; i < total; ++i)
{
addNewNumber(&array);
}

float lowest = getLowest(array, total);

printf("The lowest number is %1.0f.\n", lowest);
system("PAUSE");
return 0;
}

void addNewNumber(float *pointer)
{
float newNumber;
printf("New number: ");
scanf("%f\n", &newNumber);
*pointer = newNumber;
}

float getLowest(float array[], int length) {
float lowest = array[0];
for (int i = 0; i < length; ++i)
if (array < lowest)
lowest = array;
return lowest;
}

THe problem is that the program, when run, gets two numbers before
prompting the second time. It appears that the second number gets
added to the array. Additionally, the program always goes one cycle
longer than it should. In other words, if 10 is the first input, then
the program will scanf eleven times. I can see that that might
possibly be a problem with the for loops (though I checked them many
times to see if I had done something wrong). However, the issue of it
getting two values in a row before printing 'New Number: ', I cannot
fathom the source of. Running it over and over in my head, I cannot
see what would cause it to scan twice, given the order of the calls,
before printing a second prompt.

Thank you for any help in advance.

Yours,

James
 
B

Blue Ocean

Randy Howard said:
A problem with a compilable piece of code using a standard function
shouldn't be OT here. Why not just post the code and see what kind
of help you get?

EDIT to my above post!

My problem has been solved. I was fiddling with it and removed the \n
in the scanf() function. Now I have a question.

Does \n mean something different in scanf() than in printf()? My
manual never said anything about it. I've been told before that I
need to get a new book for C, and I will, as soon as I get back to
campus. Also, if \n does not in fact mean new line in scanf(), what
in the world does it mean? I'm going to go and hunt down an API (is
that what it's called in C?) for the standard libraries and see if I
can make sense of them.

Thank you again,

James
 
S

Sidney Cadot

Blue said:
EDIT to my above post!

My problem has been solved. I was fiddling with it and removed the \n
in the scanf() function. Now I have a question.

Does \n mean something different in scanf() than in printf()?

Yes. In scanf, a consequtive sequence of 1 or more whitespace characters
(which includes \n) counts as a 'directive' which directs scanf to
consume zero or more consequtive whitespace characters from the
originating stream.
My manual never said anything about it.

You really need a better manual :)
I've been told before that I
need to get a new book for C, and I will, as soon as I get back to
campus.

Since you have internet access, get N869 for now (the draft C99 standard):

http://www.ucalgary.ca/~bgwong/n869.pdf

This spells out the standard library semantics in quite some detail.
Check section 7.19.6.2 on precise (f)scanf format string semantics.
Also, if \n does not in fact mean new line in scanf(), what
in the world does it mean? I'm going to go and hunt down an API (is
that what it's called in C?)

It's called a standard, basically.
for the standard libraries and see if I
can make sense of them.

They're quite dense, but not too difficult to follow if you put in the
effort.

Good luck,

Sidney
 
E

E. Robert Tisdale

Blue said:
My problem has been solved.
I was fiddling with it and removed the \n in the scanf() function.
Now I have a question.

Does \n mean something different in scanf() than in printf()?
No.

> cat main.c
#include <stdio.h>

int main(int argc, char* argv[]) {
int total = 0;
printf("Numbers to sort: ");
scanf("%d\n%d", &total, &total);
printf("%d = total\n", total);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main
Numbers to sort: 22 23
23 = total

SCANF(3) Linux Programmer’s Manual SCANF(3)

NAME
scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf -
input format conversion
.
.
.

White space (such as blanks, tabs, or newlines) in the format string
match any amount of white space, including none, in the input.
.
.
.
 
N

nrk

Blue said:
Randy Howard said:
A problem with a compilable piece of code using a standard function
shouldn't be OT here. Why not just post the code and see what kind
of help you get?

I will, thanks. I will also take a look at the links that the others
posted.

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

void addNewNumber(float *pointer);
float getLowest(float array[], int length);

int main()
{
int total;

printf("Numbers to sort: ");
scanf("%d\n", &total);

Ah!! The infamous '\n' in the scanf format specifier. The problem with
this is that it consumes *any* amount of white space (space, tabs and
newlines), not just a single newline. So what happens is that after you
hit say 10\n, the '\n' in your format specifier forces scanf to keep
waiting for more input (since it consumes any amount of whitespace, it
needs to wait till it finds a non-whitespace character in the input
stream). The only way to make the scanf return is by giving a
non-whitespace input after your normal input. However, note that it won't
consume the non-whitespace input that you gave but leave it behind in the
input stream, so that your next scanf (the one with "%1.0\n") can consume
that. Of course, the same problem is again posed by the '\n' in your other
format specifier. What is the fix? Unfortunately, no straightforward one
exists. The best solution is to split up your scanf's. One to read the
integer/float and any remaining characters (discarded) in the input line,
and the next to consume the newline in the input stream. For instance:
int ret = scanf("%d%*[^\n]", &total);

if ( ret < 1 ) {
/* ret == 0 means invalid input */
/* ret == EOF means error reading input stream or end of input */
/* handle appropriately */
}
if ( !feof(stdin) ) getchar(); /* discard newline */

A fix along similar lines can be applied to your other scanf as well.
float array[total];

Variable length arrays are a C99 feature. To be portable to C89 compilers,
you will need to use dynamic memory allocation here instead of using a VLA.

HTH,
-nrk.

PS: Rest assured, your original code only reads the first <total> floats
from the input stream. You can easily construct an input to check this out
(make the least number the last one you enter, and watch as the minimum
printed by the program doesn't match this value).
for(int i = 0; i < total; ++i)
{
addNewNumber(&array);
}

float lowest = getLowest(array, total);

printf("The lowest number is %1.0f.\n", lowest);
system("PAUSE");
return 0;
}

void addNewNumber(float *pointer)
{
float newNumber;
printf("New number: ");
scanf("%f\n", &newNumber);
*pointer = newNumber;
}

float getLowest(float array[], int length) {
float lowest = array[0];
for (int i = 0; i < length; ++i)
if (array < lowest)
lowest = array;
return lowest;
}

THe problem is that the program, when run, gets two numbers before
prompting the second time. It appears that the second number gets
added to the array. Additionally, the program always goes one cycle
longer than it should. In other words, if 10 is the first input, then
the program will scanf eleven times. I can see that that might
possibly be a problem with the for loops (though I checked them many
times to see if I had done something wrong). However, the issue of it
getting two values in a row before printing 'New Number: ', I cannot
fathom the source of. Running it over and over in my head, I cannot
see what would cause it to scan twice, given the order of the calls,
before printing a second prompt.

Thank you for any help in advance.

Yours,

James
 
N

nrk

E. Robert Tisdale said:

Wrong as usual. '\n' in printf means a single newline. '\n' in scanf means
consume any amount of whitespace (spaces, tabs and newlines) from the input
stream.

To OP:

While printf and scanf formats more or less correspond to one another, you'd
be better advised to read the description of each in your compiler manual
or C book. I think trying to match up printf and scanf format strings is
comparing apples to oranges. (For instance, most scanf formats consume
leading whitespace. There is no equivalent behavior for the printf
formats). scanf has complicated semantics and unless you have a thorough
understanding, is quite hard to use correctly.

SCANF(3) Linux ProgrammerÂ’s Manual SCANF(3)

NAME
scanf, fscanf, sscanf, vscanf, vsscanf, vfscanf -
input format conversion
.
.
.

White space (such as blanks, tabs, or newlines) in the format string
match any amount of white space, including none, in the input.
.
.
.

Pay attention to the words in that description, particularly the word "any
amount".

-nrk.
 
S

Sidney Cadot


Obviously, you know too much of the subject matter to give such a
misleading answer by mistake.

I've been quite weary of people accusing you of trolling so far, since
on more than one occasion I've seen things coming from you that are
quite sensible.

However, your curious opinions on paraphrasing (to put it mildly), and
answers such as this one, really beg the question: Why-oh-why are you
behaving as you do?

I'd really appreciate a straight answer.

Best regards,

Sidney
 
C

CBFalconer

Blue said:
EDIT to my above post!

My problem has been solved. I was fiddling with it and removed the \n
in the scanf() function. Now I have a question.

How could it possibly be solved. The original didn't compile:

junk.c: In function `main':
junk.c:14: warning: ISO C89 forbids variable-size array `array'
junk.c:14: warning: ISO C89 forbids mixed declarations and code
junk.c:16: `for' loop initial declaration used outside C99 mode
junk.c:21: warning: ISO C89 forbids mixed declarations and code
junk.c: In function `getLowest':
junk.c:38: `for' loop initial declaration used outside C99 mode

Post complete compilable STANDARD C programs. You don't have a
C99 compiler, at least I am willing to put high odds against it.
 
E

E. Robert Tisdale

CBFalconer said:
How could it possibly be solved? The original didn't compile:

junk.c: In function `main':
junk.c:14: warning: ISO C89 forbids variable-size array `array'
junk.c:14: warning: ISO C89 forbids mixed declarations and code
junk.c:16: `for' loop initial declaration used outside C99 mode
junk.c:21: warning: ISO C89 forbids mixed declarations and code
junk.c: In function `getLowest':
junk.c:38: `for' loop initial declaration used outside C99 mode

Post complete compilable STANDARD C programs.
You don't have a C99 compiler,
at least I am willing to put high odds against it.
> gcc -Wall -std=c99 -pedantic -O2 -o main main.c
> gcc -Wall -std=c89 -pedantic -O2 -o main main.c
main.c: In function `main':
main.c:13: warning: ISO C89 forbids variable-size array `array'
main.c:13: warning: ISO C89 forbids mixed declarations and code
main.c:15: `for' loop initial declaration used outside C99 mode
main.c:19: warning: ISO C89 forbids mixed declarations and code
main.c: In function `getLowest':
main.c:35: `for' loop initial declaration used outside C99 mode

My GNU C99 compiler compiles it without complaint.
 
S

Sidney Cadot

CBFalconer said:
Post complete compilable STANDARD C programs.

It is a C99 program.

Although, IMHO, it's quite irrelevant, it's also compilable, using gcc
-std=c99, for example.
> You don't have a C99 compiler, at least I am willing to put high odds
against it.

In what way is that relevant?

I would agree that it is a good idea to point out to the OP that his
program uses C99 specific constructs. Given his experience, he may well
be inadvertantly using a C++ compiler instead of a C compiler.

Best regards,

Sidney
 
S

Sidney Cadot

Blue said:
[....snip.....]

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

void addNewNumber(float *pointer);
float getLowest(float array[], int length);

int main()
{
int total;

printf("Numbers to sort: ");
scanf("%d\n", &total);

float array[total];

for(int i = 0; i < total; ++i)
{
addNewNumber(&array);
}

float lowest = getLowest(array, total);

printf("The lowest number is %1.0f.\n", lowest);
system("PAUSE");
return 0;
}

void addNewNumber(float *pointer)
{
float newNumber;
printf("New number: ");
scanf("%f\n", &newNumber);
*pointer = newNumber;
}

float getLowest(float array[], int length) {
float lowest = array[0];
for (int i = 0; i < length; ++i)
if (array < lowest)
lowest = array;
return lowest;
}



Just checking: are you aware that this program uses a number of
constructs that are specific to C99 (the latest C standard)?

This code does not compile with older (C89) compilers, who are (alas!)
still far more common.

It may well be that you are inadvertently using a C++ compiler instead
of a C compiler, since the specific C99 constructs you use also happen
to be valid C++ constructs.

If the following compiles, you're using a C++ compiler:

int main(void)
{
class X;
return 0;
}

Nothing wrong with that of course, it's just that you would get better
help in comp.lang.c++ .

Best regards,

Sidney
 
B

Blue Ocean

CBFalconer said:
How could it possibly be solved. The original didn't compile:

junk.c: In function `main':
junk.c:14: warning: ISO C89 forbids variable-size array `array'
junk.c:14: warning: ISO C89 forbids mixed declarations and code
junk.c:16: `for' loop initial declaration used outside C99 mode
junk.c:21: warning: ISO C89 forbids mixed declarations and code
junk.c: In function `getLowest':
junk.c:38: `for' loop initial declaration used outside C99 mode

Post complete compilable STANDARD C programs. You don't have a
C99 compiler, at least I am willing to put high odds against it.

I'm sorry. It compiled on my system. I think I am using . . . no,
let me check. My compiler is gcc.exe, which came with the environment
I'm using, Bloodshed's Dev-C++. The help file assures me that there
is a C mode, and I know that I selected it. It seems to compile on
the C++ mode as well . . . but I'm sure, absolutely positive that I
had it on C mode earlier. I am still a bit hazy on the use of
malloc(), but I just read all about memory allocution in Stanford's
online CS library, and the word 'heap' helped a ton. I was introduced
to that concept in my CS101 course at school, but that was in its Java
manifestation.

So I assume that I need to use malloc() to make the array valid for
C89. But what does it mean about the for loop being used outside C99
mode? Is there no for loop in the ANSI C89 standard? And what does
it mean that mixed declarations and code are forbidden? Also, if I am
letting the environment compile the program for me, how do I tell it
to use C89 standard?

Yours,

James
 
C

CBFalconer

Blue said:
.... snip ...

So I assume that I need to use malloc() to make the array valid for
C89. But what does it mean about the for loop being used outside C99
mode? Is there no for loop in the ANSI C89 standard? And what does
it mean that mixed declarations and code are forbidden? Also, if I am
letting the environment compile the program for me, how do I tell it
to use C89 standard?

I am virtually certain your assumptions are wrong. I know nothing
about Bloodshed etc. and there is no such thing as 'environment
compiling', etc. Once fundamental thing about C89 is that you
should declare all variables before any code.

You need to spend some time with your compiler manuals or on a
newsgroup dedicated to it.
 

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

Forum statistics

Threads
474,135
Messages
2,570,784
Members
47,342
Latest member
KelseyK737

Latest Threads

Top