-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
No comments:
Post a Comment
Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!