0

I am trying to take input data and print it using structures. when i run this code it is not taking input for lastname. It directly asks to enter input for firstname. Can someone help me with this. Thank you.

address.c

typedef struct 
{
  char lname[25];
  char fname[20];
  char address[20];
  char phonenumber[20];
}addressbook;

addressbook a;
int main()
{
 printf("enter details:\n");
   printf("enter lastname:\n");
   gets(a.lastname);
   printf("enter firstname:\n");
   gets(a.firstname);
   printf("enter address:\n");
   gets(a.address);
   printf("enter phone number:\n");
   gets(a.phonenumber);
   printf("lastname:%s\n",a.lastname);
   printf("firstname: %s\n", a.firstname);
   printf("address:%s\n", a.address);
   printf("phone number:%s\n", a.phonenumber);
}

When I run this it is not waiting to enter the lastname. it directly goes to enter firstname.

maddy
  • 185
  • 2
  • 4
  • 9
  • 8
    Just a note: [`gets()` is dangerous](http://stackoverflow.com/questions/2843073/warninggets-function-is-dangerous) –  Aug 31 '11 at 23:20
  • 1
    gets() has been deprecated for awhile. Use getline() instead. – CoolBeans Aug 31 '11 at 23:20
  • 3
    always use `fgets` rather than `gets`, in order to avoid overflows – Chris Dodd Aug 31 '11 at 23:21
  • but appart from the obvious stack-based buffer overflow vulnerability, and after fixing your typos, the code runs fine on my computer (`gcc version 4.6.1 20110819 (prerelease) (GCC)` on Linux x86_64) – Niklas B. Aug 31 '11 at 23:23
  • 3
    Also FYI `lname` and `lastname` are not the same – Ray Toal Aug 31 '11 at 23:23
  • After changing `lname`/`fname` to `lastname`/`firstname` into the structure definition (and adding `#include ` to the top) it works fine... http://ideone.com/CnfX7 – Matteo Italia Aug 31 '11 at 23:24
  • @Chris Dodd- isnt fgets deprecated too? – CoolBeans Aug 31 '11 at 23:24
  • @CoolBeans: the problem with `gets` is that you can't tell it how big is the buffer, so it cannot be safeguarded from a buffer overflow. `fgets`, instead, allows you to specify the size of the buffer, so it's perfectly safe. (Besides, `getline` is not standard C) – Matteo Italia Aug 31 '11 at 23:24
  • 8
    You have neglected to include the code that precedes this sequence and which is leaving a stray \n in the console input buffer and is causing the problem. There was a homework problem posted earlier today that had the exact same issue, only he included the offending code sequence. – Amardeep AC9MF Aug 31 '11 at 23:26
  • @ray yes i noticed that before. I forgot to change here. Thank you – maddy Aug 31 '11 at 23:34
  • 1
    @CoolBeans: `getline` is not a standard C function. And `gets` is not "deprecated"; that implies an official body has declared it as such. – Oliver Charlesworth Aug 31 '11 at 23:38
  • @Oli Charlesworth - thanks for the clarification. I thought it was officially deprecated .. iirc GNU C compiler prints out warning as such. – CoolBeans Aug 31 '11 at 23:57
  • 3
    @Oli: Yes, `gets()` has been officially deprecated by the ISO C committee. The deprecation doesn't appear in the C99 standard, but it was added in one of the Technical Corrigenda, and appears in [N1256](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf) 7.16.9p2: "The **gets** function is obsolescent, and is deprecated." The `gets()` function is removed entirely in the current draft of the C201X standard. – Keith Thompson Sep 01 '11 at 00:52
  • @To All Experts : My gcc complier is responding well to this code. I just copied and pasted and executed. I see no problem in this code. And it is working nicely. gets() is dangerous to use,What is the relation between overflow and accepting no input??Needed explanation – Muthu Ganapathy Nathan Sep 01 '11 at 18:53

1 Answers1

0

That code won't even compile as it stands, producing (in my environment):

pax@pax-desktop:~$ gcc -Wall -Wextra -o qq qq.c
qq.c: In function ‘main’:
qq.c:12:2: warning: implicit declaration of function ‘printf’
qq.c:12:2: warning: incompatible implicit declaration of built-in function ‘printf’
qq.c:14:4: warning: implicit declaration of function ‘gets’
qq.c:14:10: error: ‘addressbook’ has no member named ‘lastname’
qq.c:16:10: error: ‘addressbook’ has no member named ‘firstname’
qq.c:21:28: error: ‘addressbook’ has no member named ‘lastname’
qq.c:22:31: error: ‘addressbook’ has no member named ‘firstname’
qq.c:25:1: warning: control reaches end of non-void function

You should always (at least initially) compile with a high warning level and take note of what the compiler is telling you:

  • you should include stdio.h if you're going to use printf and gets.
  • you should use consistent field names in your structure.
  • you should return something from non-void functions (technically this is not necessary under later versions of the standard but it's still a good idea for portability).

In addition, you may want to consider the following:

  • int main() is not one of the two canonical forms of the main function. While the standard allows for implementation-defined extra ones, the "correct" one for this particular case would be int main (void).
  • gets is a dangerous function since there is no way to prevent buffer overflow, making your code insecure. For example, if I entered a thousand characters for my first name, it may well screw up your program by overwriting huge chunks of accounting information on the stack (like return addresses for example). You can find a safer input function here.

Making most of those changes, you would end up with something like:

#include <stdio.h>

typedef struct {
    char lastname[25];
    char firstname[20];
    char address[20];
    char phonenumber[20];
}addressbook;

addressbook a;
int main (void) {
    printf("enter details:\n");

    printf("enter lastname:\n");
    gets(a.lastname);

    printf("enter firstname:\n");
    gets(a.firstname);

    printf("enter address:\n");
    gets(a.address);

    printf("enter phone number:\n");
    gets(a.phonenumber);

    printf("lastname:%s\n",a.lastname);
    printf("firstname: %s\n", a.firstname);
    printf("address:%s\n", a.address);
    printf("phone number:%s\n", a.phonenumber);

    return 0;
}

which compiles and runs okay, although it still has the serious buffer overflow vulnerability. If you want to fix that, you can refer to the link I gave.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953