Menu ↓

Reading and Printing String in C Language

Recently, I learnt an intriguing subject about the I/O problem with C programming language on the Hacker Rank. The case is reading a text from the stdin and printing the values to stdout. The problem is required to read and then print a character, a word, and a sentence.

Even though this problem is marked as easy level, with my measly knowledge of C programming language, this task indeed gave me trouble. After employing my Google-fu skills, I managed to complete the task and learn something that was worth to share.

In the problem description, it was recommended to use the scanf API from the standard input. Of course, I tackle the problem faithfully using scanf. I don't have issues reading and printing a character and a word since it's very straightforward. But, I struggle with how to read sentences.

The problem description is nice enough to explain how I can use scanf to read a sentence.

In order to take a line as input, you can use scanf("%[^\n]%*c", s); where is defined as char s[MAX_LEN] where is the maximum size of. Here, [] is the scanset character. ^\n stands for taking input until a newline isn't encountered. Then, with this %*c, it reads the newline character and here, the used * indicates that this newline character is discarded.

Note: The statement: scanf("%[^\n]%*c", s); will not work because the last statement will read a newline character, \n, from the previous line. This can be handled in a variety of ways. One way is to use scanf("\n"); before the last statement.

To be honest, the explanation is not easy to understand. I was struggling with how to implement the scanf for reading a sentence. My initial code was like this:

int main()
{
		char ch, s[100], sen[100];
		scanf("%c", &ch);
		scanf("%s", s);
		scanf("%[^\n]%*c", sen);
		printf("%c\n", ch);
		printf("%s\n", s);
		printf("%s\n", sen);
		return 0;
}

I don't know why it keeps failing. Only after I re-read the problem description, slowly and carefully, I find the problem. This note was the answer: scanf("%[^\n]%*c", s); will not work because the last statement will read a newline character, \n, from the previous line.

The issue is I need to capture the previous newline character (\n). I might not encounter this issue if I read the sentences first. But, I couldn't control the input from the Hacker Rank. So, the solution was inserting the scanf("\n"); in between of scanf("%s", s); and scanf("%[^\n]%*c", sen);.

Finally, I'm able to solve the problem with this code:

int main()
{
		char ch, s[100], sen[100];
		scanf("%c", &ch);
		scanf("%s", s);
		scanf("\n");
		scanf("%[^\n]%*c", sen);
		printf("%c\n", ch);
		printf("%s\n", s);
		printf("%s\n", sen);
		return 0;
}

Psstt, the scanf("\n") could be replaced with getchar().

After completing the task, as usual, I go to the discussion panel to see other solutions. I found one solution that does not use scanf but uses gets. So, I started to research this gets API.

The first impression about gets API is, it's easy to use compared with scanf. However, my research found that the gets API is in fact deprecated and I should use fgets API. It's mentioned that gets API is often causing a buffer overflow.

Interestingly, when I use gets API, I get this error when trying to compile the code:

$ gcc main.c -o sen
main.c: In function ‘main’:
main.c:8:5: warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]
    8 |     gets(sen);
      |     ^~~~
      |     fgets
/usr/bin/ld: /tmp/cchC6KIV.o: in function `main':
main.c:(.text+0x37): warning: the `gets' function is dangerous and should not be used.

For your information, this is my GCC version:

$ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Of course, replacing the gets with fgets make me able to compile the code.

#include <stdio.h>

int
main()
{
    char sen[100];
    printf("Read sentence with gets:\n");
    fgets(sen, 100, stdin);
    printf("The sentence is:\n %s\n", sen);
    return 0;
}

All the scanf, gets, and fgets is part of the stdio API. So, don't forget to include it. #include <stdio.h>

Menu Navigation