GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 24-Mar-2008, 17:07
aijazbaig1's Avatar
aijazbaig1 aijazbaig1 is offline
Member
 
Join Date: May 2006
Location: India
Posts: 155
aijazbaig1 has a spectacular aura aboutaijazbaig1 has a spectacular aura about
Question

Scanning dilemma (fscanf and fgets)


hello,

I have been trying to write a simple refresher program which writes stuff into an array of structs and then tries to read that stuff out to the console.

Ive used functions for both the tasks mentioned above

Heres the code:
CPP / C++ / C Code:
#include <stdio.h>
#include <string.h>

typedef struct {                     /* the structure type */
    char lname[20];             /* last name */
    char fname[20];             /* first name */
    int age;                    /* age */
    float rate; /* e.g. 12.75 per hour */
    //    tag* nxt_one;/*pointer to the next item*/                 
} tag;

tag my_lst[10];/* array of structs */
tag* fill_in(tag p[]); /*function to add elements to the array*/ 
void list_names(tag p[]);  /* list names of the people */

int main(void)
{
    tag *last_added;         /* a pointer to a structure */
    last_added = fill_in(my_lst);
    puts("the last person you added was");
    printf("%s %s\n",last_added -> fname,last_added -> lname);
    list_names(my_lst);          /* pass the pointer */
    return 0;
}

tag* fill_in(tag p[])

{
    int i;
    for (i=0;i<=9;i++)
        {
            puts("\nenter first name");
            fscanf(stdin,"%s",p[i].fname);
            //fgets(p[i].fname,20,stdin);
            puts("enter last name");
            //fgets(p[i].lname,20,stdin);
            fscanf(stdin,"%s",p[i].lname);
            puts("enter age");
            fscanf(stdin,"%d",&(p[i].age));
            puts("enter rate");
            fscanf(stdin,"%f",(&p[i].rate));
        }
    return &(p[i-1]);
}
void list_names(tag p[])
{
    for(int i=0;i<=9;i++)
        printf("\n%s %s\n",p[i].fname,p[i].lname);
    //    printf("\n%s ", p->fname);  /* p points to a structure */
    //    printf("%s ", p->lname);
    //    printf("%d\n", p->age);
}

Heres the make file:
Code:
CC = gcc CFLAGS = -std=c99 -Wall -W -pedantic arr_strct: arr_strct.o $(CC) arr_strct.o -o arr_strct arr_strct.o: arr_strct.c $(CC) $(CFLAGS) -c arr_strct.c clean: rm -f *.o arr_strct
What is happening here is that after the first iteration, the program doesn't wait for the user to input the first name and in the subsequent iterations, it doesn't wait for the rate as well..and so on.

I assume it has got to do something with the clearing of the input streams. What would be the best way to read streamed user input like this into different variables?

I think I somehow need to take care of clearing the string so that it may be ready to accept new user input

Additionally in both of the functions in the code above viz. fill_in and read, I was initially using a formal parameter of the type pointer to tag which I later changed to the type tag p[ ].

The previous pointer declaration was giving me errors whenever I was using the '->' operator to access various elements (to write user data to) in the fscanf and the fgets statements.

eg. With tag *p as the formal parameter in function fill_in I was using it in the fscanf statement as: fscanf(stdin,"%s",p[i] -> fname); The compiler was then flagging me a type mismatch error withn regards to 'p'. It said: error: invalid type argument of `->'

What is the difference between declaring the formal parameter to be an unconstrained array (tag p[ ]) and as a pointer (tag *p)? And how exactly was it affecting its use in fscanf/fgets

Hope to hear from you guys,

Best Regards,

Aijaz
__________________
Hope to hear from you guys!

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

Best Regards,
Aijaz Baig.
  #2  
Old 25-Mar-2008, 09:25
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,200
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: the scanning dilemma (fscanf and fgets)


Quote:
Originally Posted by aijazbaig1
What is happening here is that after the first iteration, the program doesn't wait for the user to input the first name and in the subsequent iterations, it doesn't wait for the rate as well..and so on.
Show the input that gave you this behavior.

Change it to use three instead of ten inputs, and show us what happened in the program. Just paste the output into your post.

For example, with that change and no other changes in your code:
Code:
enter first name Zaphod enter last name Beeblebrox enter age 450 enter rate 99.9999 enter first name John enter last name Galt enter age 40 enter rate 12.34 enter first name Fred enter last name Flintstone enter age 10000 enter rate 0.0001 the last person you added was Fred Flintstone Zaphod Beeblebrox John Galt Fred Flintstone


Quote:
Originally Posted by aijazbaig1
I assume it has got to do something with the clearing of the input streams.
I would assume nothing of the sort.
Quote:
Originally Posted by aijazbaig1
...I was initially using a formal parameter of the type pointer to tag which I later changed to the type tag p[ ].
Show what you actually tried. From any standard C compiler's point of view, there is no difference. See Footnote. There is certainly no difference with gcc. I rarely make flat statements, but that's a flat statement. There is no difference. Period. Full Stop.


Quote:
Originally Posted by aijazbaig1
The previous pointer declaration was giving me errors whenever I was using the '->' operator to access various elements (to write user data to) in the fscanf and the fgets statements.
Then you were doing something wrong in the fscanf and fgets statements. Show the code and show the error messages.

Quote:
Originally Posted by aijazbaig1
. With tag *p as the formal parameter in function fill_in I was using it in the fscanf statement as: fscanf(stdin,"%s",p[ i ] -> fname); The compiler was then flagging me a type mismatch error withn regards to 'p'. It said: error: invalid type argument of `->'

Well, if p is a pointer to a struct, then you can use p->fname, to access the element that p is pointing to. However p[ i ] will be a struct, so you use p[ i ].fname to access the element that (p+i) is pointing to. Note that the notation will be the same whether the parameter is declared as tag * or tag[].
Quote:
Originally Posted by aijazbaig1
What is the difference between declaring the formal parameter to be an unconstrained array (tag p[ ]) and as a pointer (tag *p)?
There is no difference. None at all. Really.
Quote:
Originally Posted by aijazbaig1
And how exactly was it affecting its use in fscanf/fgets
There would be no difference if you used them the same way.

Regards,

Dave

Footnote: One very fundamental concept:

If p is a pointer data type and j is an integer data type, the following are taken to be identical by C compilers (C++ too)

CPP / C++ / C Code:
*(p+j)


is identical to

CPP / C++ / C Code:
p[j]

Note that an array name is treated by the compiler as a constant pointer whose value is the address of the first element of the array, so the above two expressions are also valid and the effects are identical if p is the name of an array.

Note that i am not (that's not) saying that arrays are the same thing as pointers. They are not. It's just notation. Really.

Now, consider the case where p is a pointer to a struct (notation will be the same if p is an array of structs):
CPP / C++ / C Code:
p[j].fname

is the same as

CPP / C++ / C Code:
*(p+j).fname

And that's the same as
CPP / C++ / C Code:
(p+j)->fname

In particular:

CPP / C++ / C Code:
p[0].fname

is the same as
CPP / C++ / C Code:
*(p+0).fname


and that is the same as
CPP / C++ / C Code:
p->fname
Last edited by davekw7x : 25-Mar-2008 at 09:56.
  #3  
Old 25-Mar-2008, 21:38
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,335
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all

Re: the scanning dilemma (fscanf and fgets)


See this series on scanf(). You can't get around the problems by simply switching to fscanf().
__________________

During the election they said Obama could only be elected when pigs fly. Well, we currently have an epidemic of Swine Flu. Coincidence?
  #4  
Old 26-Mar-2008, 14:23
aijazbaig1's Avatar
aijazbaig1 aijazbaig1 is offline
Member
 
Join Date: May 2006
Location: India
Posts: 155
aijazbaig1 has a spectacular aura aboutaijazbaig1 has a spectacular aura about
Lightbulb

Re: Scanning dilemma (fscanf and fgets)


Hello there,
to begin with I would like to show you the functions fill_in and list_names with tag *p as the formal parameter followed by the syntax errors that it produces on my machine. So heres the other version of the program with the modified functions:
CPP / C++ / C Code:
#include <stdio.h>
#include <string.h>

typedef struct {                     /* the structure type */
    char lname[20];             /* last name */
    char fname[20];             /* first name */
    int age;                    /* age */
    float rate; /* e.g. 12.75 per hour */
} tag;

tag my_lst[10];/* array of structs */
tag* fill_in(tag *);/*function to add elements to the array*/ 
void list_names(tag *);  /* list names of the people */

int main(void)
{
    tag *last_added;        
    last_added = fill_in(my_lst);
    puts("the last person you added was");
    printf("%s %s\n",last_added -> fname,last_added -> lname);
    list_names(my_lst);          /* pass the pointer */
    return 0;
}
tag* fill_in(tag *p)
{
    int i;
    for (i=0;i<=9;i++)
        {
            puts("\nenter first name");
            fgets(p[i] -> fname,20,stdin);
            puts("enter last name");
            fscanf(stdin,"%s",p[i] -> lname);
            puts("enter age");
            fscanf(stdin,"%d",p[i] -> age);
            puts("enter rate");
            fscanf(stdin,"%f",p[i] -> rate);
        }
    return p[i-1];
}

void list_names(tag *p)
{
    for(int i=0;i<=9;i++)
        printf("\n%s %s\n",p[i] -> fname,p[i] -> lname);
}
On compiling I get the following errors:
Code:
gcc -std=c99 -Wall -W -pedantic -c arr_strct.c arr_strct.c: In function `fill_in': arr_strct.c:33: error: invalid type argument of `->' arr_strct.c:35: error: invalid type argument of `->' arr_strct.c:37: error: invalid type argument of `->' arr_strct.c:39: error: invalid type argument of `->' arr_strct.c:41: error: incompatible types in return arr_strct.c: In function `list_names': arr_strct.c:47: error: invalid type argument of `->' arr_strct.c:47: error: invalid type argument of `->' gmake: *** [arr_strct.o] Error 1

Secondly with the previous version of the program which you saw in my earlier post above (plus some minor cosmetic changes for better readability), and with the number of iterations changed to 4 I get the following output
Code:
enter first name vnsdsa enter last name scskcas enter age sdvsv enter rate enter first name enter last name svms enter age lkscklsc enter rate enter first name enter last name aldma enter age slvlsv enter rate enter first name enter last name scmac enter age slvms enter rate the last person you added was slvlsv scmac the following are the employees with their rates vnsdsa scskcas 0.000000 sdvsv svms 0.000000 lkscklsc aldma 0.000000 slvlsv scmac 0.000000
Sorry for the extremely poor choice of names but I wanted to put this to test quickly.

So guessing from the run what I can say is that on entering a textual input for a function that expects to receive an integer the program goes crazy and behaves in a weird pattern. Additionally the rate variable remains uninitialized and hence stands at 0,000000 for all the employees. What strikes me is that what I entered for age in the first iteration turns up in place of [i]p.fname in the second iteration which is rather strange. But as waltp has said fscanf and all variants of scanf are rather strange.

What do you think is causing such havoc and what would be the best way to avoid such strange behavior?..do u think doing a typecheck on what the user inputs using functions like !(isalpha) the way to go about it?

Hope to hear from you,
__________________
Hope to hear from you guys!

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

Best Regards,
Aijaz Baig.
  #5  
Old 26-Mar-2008, 15:09
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,200
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Scanning dilemma (fscanf and fgets)


Quote:
Originally Posted by aijazbaig1
On compiling I get the following errors:

OK, here we go:
Quote:
Originally Posted by aijazbaig1
Code:
arr_strct.c:33: error: invalid type argument of `->'

In the function declaration, the variable p is a pointer to a struct. Therefore, as I tried to point out, p[i] is a struct, and, given that fname is the name of an array, the way you use fgets() to read something into the fname member could be
CPP / C++ / C Code:
        fgets(p[i].fname, 20, stdin);
Quote:
Originally Posted by aijazbaig1
Code:
arr_strct.c:35: error: invalid type argument of `->'
lname would be handled the same way as fname, right?
Quote:
Originally Posted by aijazbaig1
Code:
arr_strct.c:37: error: invalid type argument of `->'

Since age is an int variable, you need its address in the scanf function, so the way to read something into that, using fscanf could be:
CPP / C++ / C Code:
        fscanf(stdin, "%d", &p[i].age);

(More about that in a minute.)

Quote:
Originally Posted by aijazbaig1
Code:
arr_strct.c:39: error: invalid type argument of `->'
Since rate is a floating point variable, you need its address in the scanf statement, so the way to read something into that, using fscanf could be:
CPP / C++ / C Code:
        fscanf(stdin, "%f", &p[i].rate);
Quote:
Originally Posted by aijazbaig1
Code:
arr_strct.c:41: error: incompatible types in return
At some point you are going to have to start looking at the messages and looking at the code.
What is the declared return type of the function that you wrote. What is the data type of of the expression is in your return statement?
Quote:
Originally Posted by aijazbaig1
...I get the following output
Code:
enter first name vnsdsa enter last name scskcas enter age sdvsv enter rate enter first name enter last name

So, there are some questions that you have to ask yourself when this happens (If you don't know, don't guess; I'll tell you in a minute).

1. What is the data type of whatever it is that you are trying to read after the enter age prompt?

2. What did you enter?

3. What happens when fscanf can't convert the input to the indicated data type?
Quote:
Originally Posted by aijazbaig1
So guessing from the run what I can say is that on entering a textual input for a function that expects to receive an integer the program goes crazy and behaves in a weird pattern.

Oh, you already guessed. Well, I would say that you are a bad guesser. The pattern is absolutely predictable; it just doesn't do what you apparently want it to do. (And what is it that you want it to do?)

I'm not sure what you expect it to do when you give it an invalid input. But here's what it does:

With a "%d" format specifier, scanf ignores leading whitespace (including the newline character left in the buffer from the previous input), then it converts as much of the input as it can and stops when it encounters something that is not a decimal digit. Since the first non-whitespace character that it sees is the character 's', it stops right there. The next scanf will start at that same position. (Scanf did not change the contents of the memory location where you told it to store the integer.)

The next scanf statement is with a "%f" format, so it tries, but fails to convert something starting with a 's' to a floating point number, so it stays right there for the next scanf statement.

Bottom line: When reading numerical quantities, you should always (always) test to see whether scanf was successful. If not, then you can try to recover (in a number of different ways), or you can simply make the program quit.

For example:
CPP / C++ / C Code:
#include <stdlib.h>
.
.
.
        if (fscanf(stdin, "%d", &p[i].age) != 1) {
            printf("Invalid input\n");
            exit(EXIT_FAILURE);
        }
.
.
.


Regards,

Dave

Footnote:
Quote:
Originally Posted by aijazbaig1
But as waltp has said fscanf and all variants of scanf are rather strange.

I'm not sure that those are the exact words that Walt used, but even if they are, it's a matter of opinion. I don't find anything strange about their behavior. (But that's only my opinion.) The functions are well-defined in the C standard, and act in predictable ways. Now Walt and I both have a problem with the way you used fscanf("%s"...), since there is no way to protect excessive user input from overflowing your input array, and that leads to undefined behavior (the dreaded "buffer overflow" problem that has lead to so many virus and other exploits). There is a way, but that ain't it.

But that's another story. I just wanted to get you past the point where you were guessing at what is happening and wasting your time trying to do things that wouldn't help to get your program running.
  #6  
Old 26-Mar-2008, 16:26
aijazbaig1's Avatar
aijazbaig1 aijazbaig1 is offline
Member
 
Join Date: May 2006
Location: India
Posts: 155
aijazbaig1 has a spectacular aura aboutaijazbaig1 has a spectacular aura about
Smile

Re: Scanning dilemma (fscanf and fgets)


HI.

Thnks for pointing out a lot of things there. In particular what I missed was that when I declare the formal parameter as tag *p instead of tag p[], the way to access an element of the structure is still the same viz. p[i].element_name.

This would have been different if I would have had just a single struct to access as in:
p -> element_name. What I forgot was that the array notation p[i] automatically translates into *(p + i) so after pointing to the correct address it gets deferenced..

...what I even missed was that p[i] would be evaluated first followed by the dot operator and hence a lot of confusion ensued..well..it was really silly..but.thats a part of learning I guess...constructive criticism always helps...

Furthermore, with regards to the scanf issue I should have read about the behavior of scanf in a bit more detail..I should not take the functionality of such oft-used naive looking functions for granted.. ..theres a lot more to it than just scanning user input...

Quote:
With a "%d" format specifier, scanf ignores leading whitespace (including the newline character left in the buffer from the previous input), then it converts as much of the input as it can and stops when it encounters something that is not a decimal digit. Since the first non-whitespace character that it sees is the character 's', it stops right there. The next scanf will start at that same position. (Scanf did not change the contents of the memory location where you told it to store the integer.)

The next scanf statement is with a "%f" format, so it tries, but fails to convert something starting with a 's' to a floating point number, so it stays right there for the next scanf statement.
On this basis I can safely say that this is the very reason that the program does not wait for the user to input 'rate' during the first iteration and 'first name' during the second iteration.

..as it safely scans in whatever is currently in the input buffer(until the first whitespace) into the memory location where p[1].fname resides. Hence p[1].fname gets the chars that I entered for p[0].age isn't it?

Hence now I know why it waits for 'lname' but not for 'fname. And the pattern repeats itself over all the iterations. So I guess for the last iteration when I enter some non-numeric chars for age, scanf stops at the first letter but the program quits. So it means that my input buffer is still populated with 'slvms' isn't it?

Well..now I do see things much more clearly...well..I should be doing much more reading for sure....
__________________
Hope to hear from you guys!

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

Best Regards,
Aijaz Baig.
  #7  
Old 26-Mar-2008, 17:21
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,200
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Scanning dilemma (fscanf and fgets)


Quote:
Originally Posted by aijazbaig1
...more reading....

It's always OK to ask. No one was born knowing this stuff, and they don't always cover it in elementary courses or textbooks (or maybe they don't emphasize it enough for it to soak in).

Regards,

Dave
  #8  
Old 27-Mar-2008, 09:27
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,200
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Scanning dilemma (fscanf and fgets)


Quote:
Originally Posted by aijazbaig1
...
Hence now I know why it waits for 'lname' but not for 'fname...
Your first post used scanf() everywhere. (Actually it used fscanf(stdin...) but, as Walt pointed out, that's really the same as scanf().)

My response and example run of the program showed that it could actually work for some user inputs.

In a later post I pointed out what you should do if you use scanf() for numeric variables. I also mentioned using scanf("%s"...) is not safe, since users could enter more chars than the array could handle, leading to buffer overrun that causes undefined behavior.

In your second post you mixed fgets() and scanf(), and that leads to problems that you must handle. It's do-able, but requires a little study.

So, here's a summary of "string" reading functions for char arrays:

scanf("%s", x)
  1. Skips leading whitespace. That is, it skips tab, space, newline chars in the input buffer until non-whitespace char is encountered.
  2. From that point, stores successive chars into the array elements starting at the memory location whose address is given in the variable x.
  3. Stops when a whitespace char is encountered, and stores a terminating zero byte in x at the end of the user inputs. (So, the result in the x array is a valid C-style "string.")
  4. Does not put leading or trailing whitespace into your memory.
  5. Note that if the array has a size of n chars and the user enters more than n-1 chars, undefined behavior results, since it will be writing beyond the end of the array. With this kind of input statement, it does not and can not protect against excessive user input. Some would say that this is OK for schoolboy "toy" programs, but is not a good habit to get into. It's simply not acceptable in general.

Note that after scanf("%s",...) or scanf("%d",...) or scanf("%f",...) there is always at least a newline char left in the input buffer. That bears repeating: There may be more stuff, but there is always a newline left in the system input buffer that will be encountered by the next scanf() (or fgets(), or getchar(), or whatever).

Now, it is possible to use scanf to read a "string" that is safe (that is will not overrun your buffer).

I'll give an example.
Suppose you have the following:

CPP / C++ / C Code:
char x[20];
.
.
.
scanf("%19s", x);

Now, after skipping leading whitespace (if any), scanf will read at most 19 chars from user input. It will stop scanning at that point (so if there were more than 19 chars in the input buffer, they are still there for the next scanf or other input function). A terminating zero-byte is stored in the x array after all of the user input chars that it got. (So the array size must be at least one more than the number you use in the format specifier.)

If the user enters fewer than 19 chars, then that many are stored in x, and a terminating zero byte is stored. The newline char is not stores in the array; it is left in the input buffer.

This is "safe," since it won't write more chars than your array must hold. Note that it always writes the terminating zero byte, so the result in the x array is a legal C-style "string."

Note that if the user enters more than 19 chars, the rest of them are still in the input buffer. If you want to empty out the input buffer so that the next input function starts on a "fresh" user input line, then it's simple. One way: A loop that reads and discards chars until it has found the newline at the end of the user input:

CPP / C++ / C Code:
    while (getchar() != '\n')
        ;

A reminder: If the next input function that your program will use is another scanf() for a "string" or a numeric quantity, and the only thing left in the input buffer is the newline char, it is not necessary to "eat" it, since leading whitespace will be ignored by the next scanf

Now, here's the way that many experienced programmers use:

fgets(buffer, size, stdin)

Properties of fgets()
  1. Does not ignore leading whitespace. If there is anything left from a previous input function like scanf(), it is read by fgets()
  2. Fgets reads all chars in the input buffer and stores them in your array until either
    a. size-1 chars are read

    or

    b. A newline char is encountered

    whichever happens first.

    Then it stores a terminating zero byte in your array.
  3. Note that all user input is stored, including the newline char. (So, if you are going to use it for something that isn't supposed to have a newline char, you have to get rid of it in your array.)
  4. Note that if the user entered more than size-1 chars before pressing Enter, the rest of the stuff is left for the next fgets() or other input funciton.
  5. Note particularly, that if the previous input was from scanf(), the newline char (and maybe more stuff) is still in the input buffer, so fgets() will not start on a new user input line, but will take the old stuff. That's why, when you mix scanf() for strings or numeric data with fgets() you must always make sure the input buffer is empty before calling fgets().

If this seems to be a lot of hassle for simple programs, maybe it is. And some people may even say that simple programs may not need the "protection" that assures no buffer overruns, but for purposes of establishing reasonable programming practices that will take you forward, I think that getting into the habit of protecting programs from invalid user input programs is a vital part of your development.

Today, even after all of those years of experience with exploits (virus and other) of "buffer overruns," and with all of the years of experience with and knowledge of ways to prevent them, we still see (sometimes, several times a week) new security alerts concerning with old, established and respected programs. (Windows and Linux applications, too).

Summary
  1. If you mix scanf() and fgets(), you must always make sure the previous newline char from scanf()has been "eaten" before the next fgets().
  2. The nice thing about using fgets() for everything: You don't have to worry about previous newline chars.
  3. The thing to remember about fgets(): You usually have to eliminate the newline char from your input buffer after fgets() does its thing.
  4. Whether you use scanf with a numeric limiter on the format specifier (like "%19s") or fgets(), you have to take into account the fact that there may be some other user input in the input buffer. Sometimes you want to "eat" it; sometimes you may want to inform the user that the "string" was too long and give the user another chance; sometimes you may want to cause the program to exit; whatever...
    But you must deal with it.


Regards,

Dave
  #9  
Old 28-Mar-2008, 00:19
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,335
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all

Re: the scanning dilemma (fscanf and fgets)


Quote:
Originally Posted by WaltP
See this series on scanf().
I take it you didn't bother to look at the link I mentioned...

Lucky for you Dave doesn't mind typing a lot to explain in detail what you could have learned in a few minutes by following a simple link.
__________________

During the election they said Obama could only be elected when pigs fly. Well, we currently have an epidemic of Swine Flu. Coincidence?
  #10  
Old 28-Mar-2008, 03:00
aijazbaig1's Avatar
aijazbaig1 aijazbaig1 is offline
Member
 
Join Date: May 2006
Location: India
Posts: 155
aijazbaig1 has a spectacular aura aboutaijazbaig1 has a spectacular aura about

Re: Scanning dilemma (fscanf and fgets)


Hi there walt.
Well..I should certainly have done that..when I look over it now..it has some pretty fine examples...you guys are doing a great job...better than a lot of texts out there (when it comes to explanation).

Thanks again for reminding me on that link. I am planning to take a hard copy of some of the threads that I have started over time plus some very important articles like that one. I cannot seem to find the printable version of that article.

Additionally the printable version of threads comes up with the code part all garbled ..like this.

It would be great if one would be able to print these wonderful articles and discussions so as to refer to them whenever needed.

Hope to hear from you soon,

Regards,
__________________
Hope to hear from you guys!

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

Best Regards,
Aijaz Baig.
 
 

Recent GIDBlogToyota - 2009 May Promotion by Nihal

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 01:03.


vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.