Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Using gets instead of scanf

  1. Nov 16, 2016 #1
    So please I'm quite new at C programming. I've been using scanf a lot in my codes but I also encounter some problems with it and I have been told to try and avoid using scanf.
    Now I'm learning getc function, but don't quite get it fully. I've surfed the net and all I see are very basic examples.

    Please why does the code below compiles well but doesn't execute fully? Also is there a way to take in integers without using scanf i.e without using something like

    Code (Text):

    Code (Text):

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

    int main()
     char *name;
     printf("Enter full names: ");
     printf("Thank you Mr. %s",name[0]);
     return 0;
    Last edited: Nov 16, 2016
  2. jcsd
  3. Nov 16, 2016 #2


    User Avatar
    Science Advisor
    Gold Member
    2017 Award

    People may object to scanf because it is vulnerable to string overflows.
    Your code uses gets. I think it has the same problem as scanf. If you are worried about string overflows, you should treat it like scanf.
    For my own use and use by trusted code, I never worried about string overflows. But string overflows are a way that hackers can insert their own code into your program. So you should avoid it in distributed public code.

    Microsoft compilers include a scanf_s (the '_s' stands for safe), which includes a parameter for the maximum number of characters to read. That is safe to use. Other compilers might have something similar; I don't know.

    getc is very basic and is tedious to work with directly unless you need the program to respond before the user hits Enter. But you can use it in a utility that gives you a safe scanf. If you are not using a Microsoft compiler, you can write your own scanf_s.
  4. Nov 16, 2016 #3


    Staff: Mentor

    C has several input functions getc() gets one character from the terminal. You are responsible for taking the character and appending it to a string or validating it depending on your needs.


    I often used gets() to get a string of input terminated when a \r character (CR or carriage return) was entered then I would validate it and if it was numeric then I'd use the sscanf() or atoi() or atof() to decode it depending on what I was trying to do.

    Every programmer has a different take on it:

  5. Nov 16, 2016 #4


    Staff: Mentor

    There are a couple things wrong with your code.
    1. name is declared as a pointer to a char, but no space is allocated for the storage of whatever characters will eventually be read in. Since you're new at C, I won't suggest using malloc() to allocate space on the heap. Instead, declare name as an array of type char, with enough space in the declaration to hold the full name.
    Something like this:
    Code (C):

    char name[30];
    Now, as long as someone enters a name with 29 or fewer characters, the above will be fine. The reason for 29 rather than 30 is to leave room for the terminating null character.
    2. name[0] represents only a single character, not the address of all of the characters in the string. Instead, do this:
    Code (Text):
    printf("Thank you Mr. %s", name);
  6. Nov 17, 2016 #5
    I would not recommend using either one of them, because as said above, both risk buffer overflow.

    It's important to understand what the keyboard input actually is. It actually has nothing to do with the keyboard, you probably know that you can pipe the output of one process as the input of another. So what's actually happening?

    It's a file descriptor ;) All programs have at least three "files" open at any given time: stdin, stdout, and stderr. You can treat them exactly like FILE descriptors. So in order to read from stdin (which is your keyboard in this case) with a known buffer size:

    Code (Text):
    char buffer[30];
    size_t charactersRead = fread(buffer, sizeof(char), sizeof(buffer) - 1, stdin);  //-1 to save room for the null terminator
    buffer[charactersRead] = '\0';  //You have to add your own null terminator in this case
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted