Strings in c gets(), fgets(), getline(), getchar(), puts(), putchar(), strlen()
Written by
Table of content
Introduction:
- An array of characters is commonly called as strings.
- They are used by programmers to manipulate texts or sentences.
- In real time, we use a lot of applications which processes words and sentences to find pattern in user data, replace it , delete it , modify it etc.
- They are widely used in spell checkers, spam filters, intrusion detection system, search engines, plagiarism detection, bioinformatics, digital forensics and information retrieval systems etc.
Strings in C:
- A string or array of characters is terminated by a null character ‘\0’.
- After the last character in a string it is followed by a null character to denote the end of string.
- Syntax to declare string: data_type array/string_name [] = {“text”};
- Example:
char string_first[]="Hello World";
The above example declares a string called ‘string_first’, with ‘Hello World’ as the text inside it. You do not need to specify the size of array when declaration is made in the above fashion. The null character gets implicitly added into the string.
This is the default method of string declaration in C and is called as declaration of string constant as value is pre-assigned to the string.
The above statement can be also declared as follows:
char string_first[12] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' ,'\0'};
Note that here we have to include space and null character as separate characters as they are too part of string. This is the classic array declaration method that we have used above for strings.
You can even declare a string as:
char name[size];
However, always remember that the you will be able to store size-1 characters as the last character will be null.
Memory Representation:
char string[] = {"Hello"};
Index | 0 | 1 | 2 | 3 | 4 | 5 |
String / Array | H | E | L | L | O | \0 |
Address | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 |
Thus, character at string[1] = E, similar to how we access array elements.
Since char data type occupies 1 byte in memory hence the address space increments by 1 byte. As seen , null character will always be the termination of the string. Thus, string is nothing but a sequence of characters.
Reading Strings:
There are multiple methods using which a string can be read which has been entered by user.
Consider:
string; str[] = “Hello World”;
- Using scanf() function:
- Using scanf, a string can be read as follows :
scanf(“%s”, str);
- However when you will try and display the content of ‘str’ , it will only output Hello, why is it so ?
- The main drawback of scanf to use to input string; is that the function terminates as soon as it finds a blank space. Since we have a blank space after ‘Hello’, hence only Hello gets stored inside str.
- Also note that, for scanning strings, you do not need the ampersand character precede the string name str.
- Null character gets automatically appended on encountering a blank space to mark the end of string.
- Using gets() function in C : (Should no longer be used):
-
- Using gets(), string can be read as follows:
gets(str);
- gets() overcomes the shortcomings of scanf(). Gets stands for get string.
- In this case, the entire string “Hello Word” will be read by the function.
- The function takes starting address of the string which will hold the input and automatically appends the null character at the end of the string.
- This function is deprecated – that means it is obsolete and it is strongly suggested we do not use it — because it is dangerous.
- It is dangerous because it provides no protection against buffer overflow; overflowing the string into which it is saving data. Programs that use ‘gets’ can actually be a security problem on your computer. Since it is sometimes used in older code (which is why the GNU C Library still provides it), we need to understand how it is used.
- The gets function takes one parameter, the string in which to store the data which is read. It reads characters from standard input up to the next newline character (that is, when the user presses Enter button ), discards the newline character, and copies the rest of the data into the string. If there was no error, it returns the same string ; otherwise, if there was an error, it returns a null pointer.
- gets is the easiest to use, however should be avoided as far as possible to avoid unreliable behaviour.
- We shall see going ahead our first string operation example using gets().
- Using fgets() function: (Should no longer be used):
- The fgets (“file get string”) function is similar to the gets function.
- Rather than reading a string from standard input, fgets reads it from a specified stream, usually file stream up to and including a newline character.
- It stores the string in the string variable passed to it, adding a null character to terminate the string.
- This function takes three parameters: the first is the string into which to read data, the second is the maximum number of characters to read. The third parameter is the stream from which to read. The number of characters that fgets reads is one less than than number specified; it stores the null character in the last character space.
- You must supply at least as many characters of space in the string, or your program might crash, but at least the fgets function protects against overflowing the string and creating a security hazard.
- If there is no error, fgets returns the string read as a return value else for example if the stream is already at end of file, it returns a null pointer.
- Unfortunately, like the gets function, fgets is deprecated, in this case because when fgets cannot tell whether a null character is included in the string it reads.
- If a null character is read by fgets, it will be stored in the string along with the rest of the characters read. Since a null character terminates a string in C, C will end your string prematurely, right before the first null character.
- Only use fgets if you are certain the data read cannot contain a null; otherwise, use getline.
- Syntax:
char *fgets(char *str, int n, FILE *stream)
str is the pointer to an array of chars i.e the string ; n is the maximum number of characters to be read including the null character; FILE *stream is the pointer to object that identifies the stream where characters are read from. Usually used with file stream. However, standard input stream is also acceptable.
- Using getline() function in C: (Preferred Method):
-
- The getline function is the preferred method for reading lines of text.
- The other functions like gets, fgets, and scanf, are unreliable for reasons already seen above and must be avoided.
- The getline function reads an entire line from a stream, up to and including the next newline character.
- Syntax:
size_t getline(char **lineptr, size_t *n, FILE *stream);
- It takes three parameters. The first is a pointer to a block allocated with malloc or calloc which allocates memory for the program when run. This parameter is of type char **; it will contain the line read by getline. The second parameter is a pointer to a variable of type size_t; this parameter specifies the size in bytes of the block of memory pointed to by the first parameter. The third parameter is simply the stream from where to read the line.
- The getline function automatically will enlarge the block of memory as needed, via realloc function, so there is never a shortage of space one reason why getline is safe. We will understand better in the below mentioned example.
- It will also tell us the new size of the block by the value returned in the second parameter.
- If an error occurs, such as end of file etc. being reached without reading any bytes, it returns -1.
- Although the second parameter is of type pointer to string , you cannot treat it as an ordinary string, since it may contain null characters before the final null character marking the end of the line. The return value enables you to distinguish null characters that getline read as part of the line, by specifying the size of the line.
Here is an example of how to use getline to read a line of text from the standard input.
#include <stdio.h>
int main()
{
int bytes_read;
int size = 10;
char *string;
printf ("Please enter a string: ");
/* These 2 lines are very important. */
string = (char *) malloc (size);
bytes_read = getline (&string, &size, stdin);
if (bytes_read == -1)
{
puts ("ERROR!");
}
else
{
puts ("You entered the following string: ");
puts (string);
printf ("\nCurrent size for string block: %d", bytes_read);
}
return 0;
}
Output:
Please enter a string: Hello! How have you been ?
You entered the following string:
Hello! How have you been ?
Current size for string block: 27
- Here we have typed more than 10 characters. However, getline still safely handled the input and read the data entirely as it dynamically reallocates space to accomodate the string.
- You can also observe that, the bytes_read / space allocated for the string is 27 i.e 26 characters of the string entered and one space for the null character to terminate the strung.
-
Using getdelim() function: (Preferred Method):
-
- The getdelim function is a more general form.
- getline stops reading input at the first newline character it encounters, however the getdelim function enables you to specify other delimiter characters than newline. In fact, getline simply calls getdelim and specifies that the delimiter character is a newline.
- The syntax for getdelim is nearly the same as that of getline, except that the third parameter is the delimiter character, and the fourth parameter is the stream from which to read.
- Example: Replace
bytes_read = getline (&string, &size, stdin);
with the line :
bytes_read = getdelim (&string, &size, '\n', stdin);
-
Using getchar() function:
-
- getchar() as the name states reads only one character at a time.
- In order to read a string, we have to use this function repeatedly until a terminating character is encountered.
- The characters scanned one after the other have to be stored simultaneously into the character array.
- Using getchar(), string can be read as follows:
#include <stdio.h>
int main()
{
char str[50], ch;
int i;
printf("Enter a string: ");
i = 0;
ch = getchar ();
while(ch!='\n')
{
str[i] = ch;
i++;
ch = getchar();
}
str[i] ='\0';
printf("Entered string is: %s", str);
return 0;
}
Output:
Enter a string: Where have you e# #been?
Entered string is: Where have you been?
- Here we have used the new line ‘\n’ character to be the terminating character. Hence condition is checked against it.
- Note that, you have to manually insert the null ‘\0’ character at the end of string using this method.
Printing Strings:
There are three methods using which a string can be written / displayed on screen.
Consider the
string; str[] = “Hello World”;
- Using printf() function:(Most Preferred):
- Using printf, a string can be displayed as follows : %s s the format specifier used to print a string.
- This function prints a text string to the terminal i.e stdout screen. It is one of the preferred modes to output a string.
- The entire string “Hello Word” will be printed by the function.
- It enables us to print formatted output; thus giving us flexibility.
-
Using puts() function:( Preferred):
-
- Using puts(), string can be displayed as follows: It just takes its parameter as the string to be printed.
puts(str);
- In this case too, the entire string “Hello Word” will be printed by the function.
- The most convenient function for printing a simple message on standard output is puts. It is even simpler than printf, since you do not need to include a newline character — puts does that for you.
- The puts function is safe and simple, but not very flexible as it does not give us an option of formatting our string.
- Similar to puts you have fputs() (“file put string”) function ; except that it accepts a second parameter, a stream to which to write the string. It does not add a newline character, however; it only writes the characters in the string. It returns EOF if an error occurs; otherwise it returns a non-negative integer value.
-
Using putchar() function:
-
- putchar() as the name states prints only one character at a time.
- In order to print a string, we have to use this function repeatedly until a terminating character is encountered.
- Using putchar(), string can be read as follows:
i = 0;
while(str[i]!='\0')
{
putchar( str[i] );
i++;
}
- Using sprintf() function (Deprecated):
-
- The sprintf (“string print formatted”) command takes first parameter as a string to which to send output. It terminates the string with a null character. It returns the number of characters stored in the string, not including the terminating null.
- This function will behave unpredictably if the string to which it is printing overlaps any of its arguments. We have tomake sure the size of the buffer to be written to is large enough to avoid buffer overruns. If this is not done properly, it can result in a buffer overflow, causing the program to crash at a minimum. At worst, a carefully crafted overflow can cause unexpected results.
- With sprintf (), you can combine several data variables into a character array.
Example:
#include <stdio.h>
int main()
{
char string[100];
sprintf (string, "She stood %dst in class.", 1);
puts (string);
return 0;
}
Output:
She stood 1st in class.
Notice that in order to print the output we had to support it using puts (). Thus, sprintf () is used to store formatted data as a string and should be avoided in code.
String Operations:
There are a variety of string operations that can be performed. We shall go through each one of them in the future section.
Let’s get started with the basic !
Find string length:
Approach1: Using a user define formula for length calculation:
We shall first take an input from user for the string.
- We shall set a counter to 0 in order to calculate string length.
- Until we encounter the null character ‘\0’ , which means end of string; the counter will be incremented.
Code:
#include <stdio.h>
int main()
{
char str[50];
int i; //counter that will calculate string length
printf("Enter a string: ");
gets(str);
for(i = 0; str[i] != '\0'; i++);
printf("Length of string is: %d", i);
return 0;
}
Output:
When you try to compile the code, it will compile however the compiler will throw a warning message as follows:
main.c: In function ‘main’:
main.c:8:5: warning: ‘gets’ is deprecated [-Wdeprecated-declarations]
main.c:(.text.startup+0x2c): warning: the `gets' function is dangerous and should not be used.
Thus, it warns us that gets () is a deprecated and dangerous function and should be hence avoided.
However, if you go ahead and run the program you will get the below output:
Enter a string: hello world !
Length of string is: 13
The length of string is 13 because 5 characters in Hello, one space character, 5 characters in world, one more space and another ‘!’ character.
Approach 2: Using predefined function strlen() :
Function: The function takes a single argument, i.e, the string variable whose length is to be found, and returns the length of the string passed. The strlen() function is defined in <string.h> header file.
Syntax:
size_t strlen(const char *str)
Code:
#include <stdio.h>
#include<string.h> //include header file containing strlen() definition
int main()
{
char str[50];
printf("Enter a string: ");
gets(str);
printf("Length of string is: %d", strlen(str)); //calculating and printing length of string, funtion returns an integer value
return 0;
}
Output:
Enter a string: How you doing?
Length of string is: 14
Note:
- Remember! Avoid using deprecated functions in your code. Always use alternatives available like getline, getdelim for input and for output.
- There are library functions available for most of the string operations which are a part of ‘string.h’; header file. However, some of the functions under it are also deprecated and should not be used. We shall have look at them while working with various string operations.
Related:
Sort characters in a string in alphabetical order
Program in C to delete the vowels in a string