I am trying a simple exercise from K&R to append string2 at the end of string1 using pointers. In case of overflow i.e. buffer of string1 can't contain all of string2 I want to prompt the user to re-enter string2 or exit.
I have written the following code:
#include<stdio.h>
#include<string.h>
#define MAXLINE 1000
int get_input(char *s);
int str_cat(char *s, char *t);
void main()
{
char input1[MAXLINE], input2[MAXLINE], c;
get_input(input1);
check:
get_input(input2);
if((strlen(input1) + strlen(input2) + 2) <= MAXLINE)
{
str_cat(input1, input2);
printf("%s\n", input1);
}
else
{
input2[0] = '\0';
printf("String overflow\n Press: \n 1: Re-enter string. \n 2: Exit.\n");
scanf(" %d", &c);
if(c == 1){
input2[0] = '\0';
get_input(input2);
goto check;
}
}
}
int get_input(char *arr)
{
int c;
printf("Enter the string: \n");
while(fgets(arr, MAXLINE, stdin))
{
break;
}
}
int str_cat(char *s, char *t)
{
while(*s != '\0')
{
s++;
}
while((*s++ = *t++) != '\0')
{
;
}
*s = '\0';
}
Initially, I was using the standard getchar()
function mentioned in the book to read the input in get_input()
which looked like this:
int get_input(char *arr)
{
int c;
printf("Enter the string: \n");
while((c = getchar()) != '\n' && c != EOF)
{
*arr++ = c;
}
*arr = '\0';
}
I am new and I read this and understood my mistake. I understand that one isn't supposed to use different input functions to read stdin and the '\n'
is left in the input stream which is picked by the getchar()
causing my condition to fail.
So, I decided to use fgets()
to read the input and modified the scanf("%d", &c)
as mentioned in the thread with scanf(" %d", c)
. This does work (kinda) but gives rise to behaviors that I do not want.
So, I have a few questions:
What's a better way to fgets()
from reading the input on encountering '\n'
than the one I have used?
while(fgets(arr, MAXLINE, stdin))
{
break;
}
fgets()
stops reading the line and stores it as an input once it either encounters a '\n' or EOF
. But, it ends up storing the '\n'
at the end of the string. Is there a way to prevent this or do I have to over-write the '\n'
manually?
Even though I used the modified version of scanf(" %d", &c)
, my output looks like
this: (https://i.sstatic.net/M5aX4.jpg). Despite that I get Enter the string:
twice when prompted to re-enter the second string in case of an overflow situation. Is the modified scanf()
messing with my input? And how do I correct it?
In general, do not mix fgets
with scanf
. Although it may be a bit bloaty, you will avoid many problems by being consistent with reading input with fgets
and then parse it with sscanf
. (Note the extra s)
A good way to remove the newline is buffer[strcspn(buffer, "\n")] = 0
Example:
// Read line and handle error if it occurs
if(!fgets(buffer, buffersize, stdin)) {
// Handle error
}
// Remove newline (if you want, not necessarily something you need)
buffer[strcspn(buffer, "\n")] = 0;
// Parse and handle error
int val;
if(sscanf(buffer, "%d", &val) != 1) {
// Handle error
}
// Now you can use the variable val
There is one thing here that might be dangerous in certain situations, and that is if buffer
is not big enough to hold a complete line. fgets
will not read more than buffersize
characters. If the line is longer, the remaining part will be left in stdin.