-Reading a character: getchar
-Reading formatted input: scanf
-Reading an entire line: gets
Here's a short example on how you can use any of these functions to read a string:
If you don't know what puts does, you may like to read this first.-Reading an entire line: gets
Here's a short example on how you can use any of these functions to read a string:
#include<stdio.h> int main(void) { const int LENGTH = 100; //The variable where the string will be stored char myString[LENGTH]; //Iterator for reading with getchar int i; //Reading with getchar puts("Reading the string using getchar: "); for(i=0; i<(LENGTH-1); i++) { myString[i] = getchar(); //Stops reading when the user presses ENTER if(myString[i]=='\n') { //Adds the null terminator myString[i+1]='\0'; break; } } puts(myString); //Reading with gets puts("Reading the string using gets: "); gets(myString); puts(myString); //Reading with scanf puts("Reading the string using scanf: "); scanf("%s",myString); puts(myString); return 0; }
When to use getchar?
getchar is a great function to be used when you want to limit the user input or you want to validate it (or you just want to process the input character by character). Here are some examples:
-You built a console menu, just like the one in here, and you want to read only one character
-You want to stop the user input if a certain character is encountered
#include<stdio.h> int main(void) { const int LENGTH = 200; char myText[LENGTH]; int i = 0; //The characters are put into the string until . in encountered do { myText[i] = getchar(); i++; }while(myText[i-1]!='.'); //Adding the null terminator myText[i+1] = '\0'; puts(myText); return 0; }-You want to make sure that a buffer overflow doesn't happen :-) . We will speak more about this when we get to gets.
#include<stdio.h> int main(void) { const int LENGTH = 5; char pinNumber[LENGTH]; int i; //Only 4 characters are read for(i=0; i<(LENGTH-1); i++) { pinNumber[i] = getchar(); } //Adding the null terminator pinNumber[LENGTH-1] = '\0'; puts(pinNumber); return 0; }-You want to extract only certain characters from the user's input:
#include<stdio.h> int main(void) { const int LENGTH = 5; char pinNumber[LENGTH]; int i = 0; char buffer; //Only 4 characters are read and they should be digits! while( (i<(LENGTH-1)) ) { buffer=getchar(); if( (buffer>='0') && (buffer<='9') ) { pinNumber[i] = buffer; i++; } } //Adding the null terminator pinNumber[LENGTH-1] = '\0'; puts(pinNumber); return 0; } /*Example Input: The b1rd 1s th3 w0rd. Output 1130 */TIP : Don't forget to add the null terminator to your string! If you don't know what a null terminator is, read this.
When to use scanf?
scanf should be used when you are dealing with number or otherwise other forms of formatted input. If you do not know exactly what formatted input and formatted strings are, see this. Here are some examples:
#include<stdio.h> int main(void) { //Integers int intData1,intData2; //Real double realData, realData2; //Characters char charData, charData2; //Strings char stringData[10], stringData2[10]; //Read a integer value using the decimal base puts("Write a integer: "); scanf("%d",&intData1); //Read a integer value using the hexadecimal base puts("Write a integer in hexadecimal: "); scanf("%x",&intData2); //Read a real value puts("Write a real number: "); scanf("%lf",&realData); //Discards the last character, before reading a char with scanf getchar(); //Read a character puts("Write a character: "); scanf("%c",&charData); //Read a string. A string is a pointer and you don't need the & operator puts("Write a string: "); scanf("%s",stringData); //Reading multiple values puts("Write a string, a real number and a character: "); scanf("%s %lf %c",stringData2,&realData2, &charData2); printf("Integer data: %d %x\n" "Real data: %lf\n" "Char data: %c\n" "String data: %s\n" "Multiple values: %s %lf %c", intData1, intData2, realData,charData, stringData, stringData2, realData2, charData2); return 0; } /*Example session: Write a integer: 12 Write a integer in hexadecimal: f3 Write a real number: 32.3 Write a character: x Write a string: mystr Write a string, a real number and a character: mystr 44.8 c Integer data: 12 f3 Real data: 32.300000 Char data: x String data: mystr Multiple values: mystr2 44.800000 c */There are some certain particularities to scanf:
TIP : Formatted data should be reffered through a pointer (that's why the & operator is used). String are pointers by default and the & operator should not be used on them.
TIP : You can avoid a buffer overflow, by specifying the maximum size of input when reading a string. In the example below, the limit is 4 characters + the automatically added null terminator:
#include<stdio.h> int main(void) { char myString[5]; puts("Input a string: "); scanf("%4s", myString); puts(myString); puts("No buffer overflow"); return 0; } /*Session Input a string: ThisIsGroundControlToMajorTom This No buffer overflow */TIP : If you read a character using scanf and before that you read a string or a number, you may observe that the character reading may be "skipped". This happens because the input buffer contains a newline character that remained from the previous reading (if you watch this with the debugger you shall see that your character shall be equal to 10 which is the equivalent of newline). Use getchar calls to discard extra characters from the input buffer.
PITFALL : If you read a string with scanf and it encounters a whitespace character, the function will consider it as a terminator. Use scanf to read words, not sentences :-)
When to use gets?
The main purpose of gets is to read strings that contain whitespace. Here's an example:
#include<stdio.h> int main(void) { const int LENGTH = 200; char myString1[LENGTH]; char myString2[LENGTH]; puts("Input a string: "); gets(myString1); puts("Input the same string again: "); scanf("%199s",myString2); puts("String read with gets: "); puts(myString1); puts("String read with scanf: "); puts(myString2); return 0; } /*Session Input a string: The bird is the word Input the same string again: The bird is the word String read with gets: The bird is the word String read with scanf: The */PITFALL:Unfortunately gets has many inherent problems related to buffer overflow, since you cannot specify the maximum number of character to read. This article explains it in more detail.
TIP: Just like in scanf, a null terminator is added at the end of the string replacing the newline character.
TIP: A safer alternative to gets is fgets. Here's how you can replace gets with fgets in the program above:
#include<stdio.h> int main(void) { const int LENGTH = 200; char myString1[LENGTH]; char myString2[LENGTH]; puts("Input a string: "); fgets(myString1, LENGTH-1, stdin); puts("Input the same string again: "); scanf("%199s",myString2); puts("String read with gets: "); puts(myString1); puts("String read with scanf: "); puts(myString2); return 0; }Question: In which situations do you use gets, in which situations scanf and in which situations getchar?
References:
http://www.cplusplus.com/reference/cstdio/
http://c-faq.com/stdio/index.html
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi