Problems with fgets and reading in a number

F

FakeAddress

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.name, sizeof(people.name), stdin);

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

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

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

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

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

fflush(stdin);
printf ("Enter gender (M or F): ");
scanf ("%c", &people.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.name);
printf ("%s",people.address);
printf ("%s, ",people.city);
printf ("%s",people.state);
printf (" %.5ld\n", people[1].zip);

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

printf ("\n");

} /* End for loop */

return 0;

} /* End main */
 
Z

Zoran Cutura

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.name, sizeof(people.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.address, sizeof(people.address),
stdin);

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

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

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

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

fflush(stdin);
printf ("Enter gender (M or F): ");
scanf ("%c", &people.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.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.address);
printf ("%s, ",people.city);
printf ("%s",people.state);
printf (" %.5ld\n", people[1].zip);

^^^
this ought to be


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

printf ("\n");

} /* End for loop */

return 0;

} /* End main */


HTH, HAND
 
A

A. Sinan Unur

(e-mail address removed) wrote in 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.

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.
 
G

goose

(e-mail address removed) wrote in message
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.

========================
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.name, sizeof(people.name), stdin);


it is not necessary to use sizeof with parenthesis, you
can do :
fgets (people.name, sizeof people.name, stdin);
fflush (stdin);
printf ("Enter street address: ");
fgets(people.address, sizeof(people.address),
stdin);

fflush (stdin);
printf ("Enter city: ");
fgets(people.city, sizeof(people.city), stdin);
fgets(people.city, sizeof(people.city), stdin);
fflush (stdin);
printf ("Enter state: ");
fgets(people.state, sizeof(people.state),
stdin);

fflush (stdin);
printf ("Enter zip code: ");
scanf ("%ld", &people.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.age);

fflush(stdin);
printf ("Enter gender (M or F): ");
scanf ("%c", &people.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.name);
printf ("%s",people.address);
printf ("%s, ",people.city);
printf ("%s",people.state);
printf (" %.5ld\n", people[1].zip);

^^^^^^^^^

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

]
if (people.gender == 'M')
{
printf ("He is %i years old.\n",
people.age); i years old.\n",
}
else
{
printf ("She is %i years old.\n",
people.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,
 
E

Emmanuel Delahaye

A. Sinan Unur said:
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.
 
M

Mark McIntyre

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.
 

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

Similar Threads

fgets 1
fgets 6
While and fgets 8
How to accept text and put each letter into a 2d matrix? 0
fgets behaviour with strncmp 8
gets, fgets, scanf none is safe... 20
Problem with scanf 7
fgets and variants 2

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top