Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Problems with fgets and reading in a number

Reply
Thread Tools

Problems with fgets and reading in a number

 
 
FakeAddress@NoSpam.com
Guest
Posts: n/a
 
      06-25-2003
I have two problems with a program. One is related to fgets reading
in the new line and the other is reading in a number that begins with
a zero.

===============================================
The dialog with the user should be as follows:
===============================================

Enter name: Minnie Mouse
Enter street address: 100 Disney Drive
Enter city: Orlando
Enter state: FL
Enter zip code: 99990
Enter age: 25
Enter gender (M or F): F

Enter name: Big Bird
Enter street address: 10 Sesame Street
Enter city: Funtown
Enter state: MA
Enter zip code: 01222
Enter age: 20
Enter gender (M or F): M

The information you entered is:

Minnie Mouse
100 Disney Drive
Orlando, FL 99990
She is 25 years old.

Big Bird
10 Sesame Street
Funtown, MA 01222
He is 20 years old.

==================================================
When I input the information, I get the following results:
==================================================

The information you entered is:

Minnie Mouse
100 Disney Drive
Orlando
, FL 01222
She is 25 years old.

Big Bird
10 Sesame Street
Funtown
, MA 01222
He is 20 years old.

There are two problems. First, I donít want the new line after the
city. I know it is because the fgets function is reading in the
newline, but I don't know how to delete it from the string. Also,
when I enter a zip code with a leading zero, it takes up both spots
(the first zip code should be 99990 not 01222). Here are the
suggestions regarding the input and output of the zip code given by my
instructor:

* If you use %li (instead of %ld) as the format specifier for the "zip
code" and if you enter your zip code starting with the number 0
(zero), C will interpret that number as "octal" and which will cause
erroneous results. The "%i" format specifier says to interpret any
number starting with a zero as octal. For this reason, I recommend
that you use %ld in the scanf statement when prompting the user for
the zip code.

* The above hint handles the zip code as it is being "input" using a
scanf statement. You have a different problem when you want to
"output" the zip code using a printf statement. C does not store
leading zeros. So, if the user in fact enters a zip code starting with
a zero, you need to do some extra formatting when you output the zip
code to display leading zeros if any. We have not yet covered this, so
I will give you the solution. You have 2 choices: Either: "%.5ld" or
"%05ld". Both of those format specifiers indicate that you want C to
reserve 5 spaces for the output, and if the integer value is less than
5 characters, to pad the integer with leading zeros.

========================
Here is my code so far:
========================

#include <stdio.h>
#include <string.h>

struct info
{
char name[30];
char address[30];
char city[20];
char state[3];
long int zip;
int age;
char gender;
};

int main (void)
{

int i;
char M = 'M';
struct info people[2];

for (i = 0; i < 2; i++)
{

fflush (stdin);
printf ("Enter Name: ");
fgets(people[i].name, sizeof(people[i].name), stdin);

fflush (stdin);
printf ("Enter street address: ");
fgets(people[i].address, sizeof(people[i].address),
stdin);

fflush (stdin);
printf ("Enter city: ");
fgets(people[i].city, sizeof(people[i].city), stdin);

fflush (stdin);
printf ("Enter state: ");
fgets(people[i].state, sizeof(people[i].state),
stdin);

fflush (stdin);
printf ("Enter zip code: ");
scanf ("%ld", &people[i].zip);

fflush (stdin);
printf ("Enter age: ");
scanf ("%i", &people[i].age);

fflush(stdin);
printf ("Enter gender (M or F): ");
scanf ("%c", &people[i].gender);
fflush(stdin);

printf ("\n");

} /* End for loop */

printf ("The information you entered is:\n\n");

for (i = 0; i < 2; i++)
{

printf ("%s",people[i].name);
printf ("%s",people[i].address);
printf ("%s, ",people[i].city);
printf ("%s",people[i].state);
printf (" %.5ld\n", people[1].zip);

if (people[i].gender == 'M')
{
printf ("He is %i years old.\n",
people[i].age);
}
else
{
printf ("She is %i years old.\n",
people[i].age);
}

printf ("\n");

} /* End for loop */

return 0;

} /* End main */
 
Reply With Quote
 
 
 
 
Zoran Cutura
Guest
Posts: n/a
 
      06-25-2003
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I have two problems with a program. One is related to fgets reading
> in the new line and the other is reading in a number that begins with
> a zero.
>
> ===============================================
> The dialog with the user should be as follows:
> ===============================================
>
> Enter name: Minnie Mouse
> Enter street address: 100 Disney Drive
> Enter city: Orlando
> Enter state: FL
> Enter zip code: 99990
> Enter age: 25
> Enter gender (M or F): F
>
> Enter name: Big Bird
> Enter street address: 10 Sesame Street
> Enter city: Funtown
> Enter state: MA
> Enter zip code: 01222
> Enter age: 20
> Enter gender (M or F): M
>
> The information you entered is:
>
> Minnie Mouse
> 100 Disney Drive
> Orlando, FL 99990
> She is 25 years old.
>
> Big Bird
> 10 Sesame Street
> Funtown, MA 01222
> He is 20 years old.
>
> ==================================================
> When I input the information, I get the following results:
> ==================================================
>
> The information you entered is:
>
> Minnie Mouse
> 100 Disney Drive
> Orlando
> , FL 01222
> She is 25 years old.
>
> Big Bird
> 10 Sesame Street
> Funtown
> , MA 01222
> He is 20 years old.
>
> There are two problems. First, I don?t want the new line after the
> city. I know it is because the fgets function is reading in the
> newline, but I don't know how to delete it from the string.


something along:

char *tmp = strchr( bufferusedinfgets, '\n');
if(tmp) tmp = '\0';
else /* fgets returned befor a \n occurred in the input, so my buffer was
to short for the input, probably more data needs to be read. */

> Also,
> when I enter a zip code with a leading zero, it takes up both spots
> (the first zip code should be 99990 not 01222). Here are the
> suggestions regarding the input and output of the zip code given by my
> instructor:
>
> * If you use %li (instead of %ld) as the format specifier for the "zip
> code" and if you enter your zip code starting with the number 0
> (zero), C will interpret that number as "octal" and which will cause
> erroneous results. The "%i" format specifier says to interpret any
> number starting with a zero as octal. For this reason, I recommend
> that you use %ld in the scanf statement when prompting the user for
> the zip code.
>
> * The above hint handles the zip code as it is being "input" using a
> scanf statement. You have a different problem when you want to
> "output" the zip code using a printf statement. C does not store
> leading zeros. So, if the user in fact enters a zip code starting with
> a zero, you need to do some extra formatting when you output the zip
> code to display leading zeros if any. We have not yet covered this, so
> I will give you the solution. You have 2 choices: Either: "%.5ld" or
> "%05ld". Both of those format specifiers indicate that you want C to
> reserve 5 spaces for the output, and if the integer value is less than
> 5 characters, to pad the integer with leading zeros.


The suggestions from your instructor are good and you should follow
them, but they are not related to the bug you are at. See the comments
in the code.

>
> ========================
> Here is my code so far:
> ========================
>
> #include <stdio.h>
> #include <string.h>
>
> struct info
> {
> char name[30];
> char address[30];
> char city[20];
> char state[3];
> long int zip;
> int age;
> char gender;
> };
>
> int main (void)
> {
>
> int i;
> char M = 'M';


The variable M is never used in this function.

> struct info people[2];
>
> for (i = 0; i < 2; i++)
> {
>
> fflush (stdin);


fflush may only be used with output streams. Using it with a input
stream causes undefined behavior. You need to remove all of there
fflush(stdin) calls if you want to write standard conforming code.

Instead of using fflush you might probably want to consume all
characters in the input stream up to the next \n with something along:

int c;
while( (c=getchar()) != '\n' && c != EOF);


> printf ("Enter Name: ");


The output you intend here might not actually appear to the console or
whatever is connected to the standard output stream, because the
standard output stream usually is line buffered (as long as we're talking
about some interactive device) so output might only be written when a \n
character occurs in the stream. But here you can force output by
calling

fflush(stdout);

> fgets(people[i].name, sizeof(people[i].name), stdin);


I've shown above how a trailing \n character can be removed, and you
should remove it from any input as long as the \n character does not
contribute to the "value" that is read. Obviously that is the case with
a name, a street or a city.


>
> fflush (stdin);
> printf ("Enter street address: ");
> fgets(people[i].address, sizeof(people[i].address),
> stdin);
>
> fflush (stdin);
> printf ("Enter city: ");
> fgets(people[i].city, sizeof(people[i].city), stdin);
>
> fflush (stdin);
> printf ("Enter state: ");
> fgets(people[i].state, sizeof(people[i].state),
> stdin);
>
> fflush (stdin);
> printf ("Enter zip code: ");
> scanf ("%ld", &people[i].zip);
>
> fflush (stdin);
> printf ("Enter age: ");
> scanf ("%i", &people[i].age);
>
> fflush(stdin);
> printf ("Enter gender (M or F): ");
> scanf ("%c", &people[i].gender);
> fflush(stdin);
>
> printf ("\n");
>
> } /* End for loop */
>
> printf ("The information you entered is:\n\n");
>
> for (i = 0; i < 2; i++)
> {
>
> printf ("%s",people[i].name);


When you change the input part to remove trailing newline characters
from the input, you'll have to finish line output by inserting \n
characters in your format strings.


> printf ("%s",people[i].address);
> printf ("%s, ",people[i].city);
> printf ("%s",people[i].state);
> printf (" %.5ld\n", people[1].zip);

^^^
this ought to be [i]



>
> if (people[i].gender == 'M')
> {
> printf ("He is %i years old.\n",
> people[i].age);
> }
> else
> {
> printf ("She is %i years old.\n",
> people[i].age);
> }
>
> printf ("\n");
>
> } /* End for loop */
>
> return 0;
>
> } /* End main */


HTH, HAND
--
Z ((E-Mail Removed))
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
 
Reply With Quote
 
 
 
 
Zoran Cutura
Guest
Posts: n/a
 
      06-25-2003
Richard Heathfield <(E-Mail Removed)> wrote:
> Zoran Cutura wrote:
>>

> <snip>
>>
>> char *tmp = strchr( bufferusedinfgets, '\n');
>> if(tmp) tmp = '\0';

>
> You Meant To Say:
>
> if(tmp) *tmp = '\0';


Yes I did.

--
Z ((E-Mail Removed))
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
 
Reply With Quote
 
A. Sinan Unur
Guest
Posts: n/a
 
      06-25-2003
(E-Mail Removed) wrote in news:84difvsajn8ttdq9n13h8l216c8nf8tkkr@
4ax.com:

> I have two problems with a program. One is related to fgets reading
> in the new line and the other is reading in a number that begins with
> a zero.


<snip>

> newline, but I don't know how to delete it from the string. Also,
> when I enter a zip code with a leading zero, it takes up both spots
> (the first zip code should be 99990 not 01222). Here are the
> suggestions regarding the input and output of the zip code given by my
> instructor:
>
> * If you use %li (instead of %ld) as the format specifier for the "zip
> code" and if you enter your zip code starting with the number 0
> (zero), C will interpret that number as "octal" and which will cause
> erroneous results. The "%i" format specifier says to interpret any
> number starting with a zero as octal. For this reason, I recommend
> that you use %ld in the scanf statement when prompting the user for
> the zip code.
>
> * The above hint handles the zip code as it is being "input" using a
> scanf statement. You have a different problem when you want to
> "output" the zip code using a printf statement. C does not store
> leading zeros. So, if the user in fact enters a zip code starting with
> a zero, you need to do some extra formatting when you output the zip
> code to display leading zeros if any. We have not yet covered this, so
> I will give you the solution. You have 2 choices: Either: "%.5ld" or
> "%05ld". Both of those format specifiers indicate that you want C to
> reserve 5 spaces for the output, and if the integer value is less than
> 5 characters, to pad the integer with leading zeros.


Your input related issues were answered by Zoran quite well, so I am not
going to comment on them. However, these remarks above really irk for one
simple reason: ZIP codes are not numbers! They are strings consisting
solely of digits, but they are not numeric values that you can add,
subtract etc. I really think you could avoid a lot of problems by treating
ZIP codes as what they are: Strings of 5 digits. Of course, strictly
speaking, there is also an optional 4 digit part. Anyway, unless you are
really hurting for memory, I wouldn't recommend using integers to store
things such as phone numbers, zip codes etc. Just my 2 cents.

Sinan.

--
A. Sinan Unur
(E-Mail Removed)
Remove dashes for address
Spam bait: (E-Mail Removed)
 
Reply With Quote
 
goose
Guest
Posts: n/a
 
      06-25-2003
(E-Mail Removed) wrote in message news:<(E-Mail Removed)>. ..

<snipped>

> There are two problems. First, I don?t want the new line after the
> city. I know it is because the fgets function is reading in the
> newline, but I don't know how to delete it from the string.


do you know how to *find* the character in the string ?
once you find it, you can then replace it with '\0'.

> Also,
> when I enter a zip code with a leading zero, it takes up both spots
> (the first zip code should be 99990 not 01222).


it does *not*. i've pointed out possible bugs in the
code below.

<snipped>
> ========================
> Here is my code so far:
> ========================
>
> #include <stdio.h>
> #include <string.h>
>
> struct info
> {
> char name[30];
> char address[30];
> char city[20];
> char state[3];
> long int zip;
> int age;
> char gender;
> };
>
> int main (void)
> {
>
> int i;
> char M = 'M';


what do you use this for ?

> struct info people[2];
>
> for (i = 0; i < 2; i++)
> {
> 0; i < 2; i++)
> fflush (stdin);


this, I believe is undefined behaviour, you cannot
"flush" an input stream.

> printf ("Enter Name: ");
> fgets(people[i].name, sizeof(people[i].name), stdin);


it is not necessary to use sizeof with parenthesis, you
can do :
fgets (people[i].name, sizeof people[i].name, stdin);

>
> fflush (stdin);
> printf ("Enter street address: ");
> fgets(people[i].address, sizeof(people[i].address),
> stdin);
>
> fflush (stdin);
> printf ("Enter city: ");
> fgets(people[i].city, sizeof(people[i].city), stdin);
> fgets(people[i].city, sizeof(people[i].city), stdin);
> fflush (stdin);
> printf ("Enter state: ");
> fgets(people[i].state, sizeof(people[i].state),
> stdin);
>
> fflush (stdin);
> printf ("Enter zip code: ");
> scanf ("%ld", &people[i].zip);


I would use fgets and sscanf here, but thats just a stylistic
issue, I would say.

>
> fflush (stdin);
> printf ("Enter age: ");
> scanf ("%i", &people[i].age);
>
> fflush(stdin);
> printf ("Enter gender (M or F): ");
> scanf ("%c", &people[i].gender);
> fflush(stdin);
>
> printf ("\n");
> printf ("\n");
> } /* End for loop */
>
> printf ("The information you entered is:\n\n");
> printf ("The information you entered is:\n\n");
> for (i = 0; i < 2; i++)
> {
> 0; i < 2; i++)
> printf ("%s",people[i].name);
> printf ("%s",people[i].address);
> printf ("%s, ",people[i].city);
> printf ("%s",people[i].state);
> printf (" %.5ld\n", people[1].zip);

^^^^^^^^^

thats your problem, i think you meant
people[i]
and not
people[1]


> ]
> if (people[i].gender == 'M')
> {
> printf ("He is %i years old.\n",
> people[i].age); i years old.\n",
> }
> else
> {
> printf ("She is %i years old.\n",
> people[i].age);
> }


personally, I would use a switch statement here,
and print out "he" for case 'M', "she" for case 'F'
and "it" for everything else.

this is because the user might have entered
something other than an 'F' or an 'M' for gender,
and you never checked the input to make sure that
it was sane.

>
> printf ("\n");
> printf ("\n");
> } /* End for loop */
> } /* End for loop */
> return 0;
>
> } /* End main */


hth
goose,
 
Reply With Quote
 
Emmanuel Delahaye
Guest
Posts: n/a
 
      06-25-2003
In 'comp.lang.c', "A. Sinan Unur" <(E-Mail Removed)> wrote:

> Your input related issues were answered by Zoran quite well, so I am not
> going to comment on them. However, these remarks above really irk for one
> simple reason: ZIP codes are not numbers! They are strings consisting
> solely of digits, but they are not numeric values that you can add,
> subtract etc. I really think you could avoid a lot of problems by treating
> ZIP codes as what they are: Strings of 5 digits. Of course, strictly
> speaking, there is also an optional 4 digit part. Anyway, unless you are
> really hurting for memory, I wouldn't recommend using integers to store
> things such as phone numbers, zip codes etc. Just my 2 cents.


And I will add, "have you seen zip codes in Great Britain?". There are
composed of 6 alphanumerics characters. Also, zip code can be prefixed with
the country code:

F-75005
CH-4005
B-1234

etc.

--
-ed- (E-Mail Removed) [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-library: http://www.dinkumware.com/htm_cl/index.html
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
 
Reply With Quote
 
Mark McIntyre
Guest
Posts: n/a
 
      06-25-2003
On 25 Jun 2003 19:26:43 GMT, in comp.lang.c , Emmanuel Delahaye
<(E-Mail Removed)> wrote:

>In 'comp.lang.c', "A. Sinan Unur" <(E-Mail Removed)> wrote:
>
>> Your input related issues were answered by Zoran quite well, so I am not
>> going to comment on them. However, these remarks above really irk for one
>> simple reason: ZIP codes are not numbers! They are strings consisting
>> solely of digits, but they are not numeric values that you can add,
>> subtract etc. I really think you could avoid a lot of problems by treating
>> ZIP codes as what they are: Strings of 5 digits. Of course, strictly
>> speaking, there is also an optional 4 digit part. Anyway, unless you are
>> really hurting for memory, I wouldn't recommend using integers to store
>> things such as phone numbers, zip codes etc. Just my 2 cents.

>
>And I will add, "have you seen zip codes in Great Britain?". There are
>composed of 6 alphanumerics characters.


Often seven, possibly even eight AFAIR. SE23 1EW is where I used to
live, many moons ago.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
 
Reply With Quote
 
 
 
Reply

Thread Tools

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

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with fgets reading last line over and over Trond Valen C++ 5 12-07-2005 08:23 AM
Reading Lines with Fgets(?) and a bit of C++ {Novice Programmer} AMT2K5 C++ 12 07-06-2005 08:34 PM
Reading Lines with Fgets and a bit of C++ {Novice Programmer} AMT2K5 C Programming 6 07-06-2005 02:34 AM
[URGENT] fgets reading last line in file twice DJP C++ 7 10-21-2004 09:23 AM
fgets and problems reading into array Eigenvector C Programming 12 07-29-2003 02:20 AM



Advertisments