Getchar() function logic in the following codes - c

I would like to know about the getchar() logic in the following codes...
printf("Type up to 25 characters and then press Enter. . . \n") ;
for (i = 0; i < 25; i++)
{
msg[ i] = getchar() ;
if (msg[ i] == ' \n' )
{
i--;
break;
}
}
putchar(' \n' ) ;
for (; i >= 0; i--)
{
putchar(msg[ i] ) ;
}
In the above code if i input a name,say "STACKEXCHANGE" and then hit enter it will display the word properly..but the below code works differently..
printf("What are your two initials?\n") ;
firstInit = getchar() ;
lastInit = getchar() ;
In this example, if i type "ST" and then hit enter, 'S' will be stored in firstinit, while "\n" will be stored in lastInit instead of 'T'.
How does this happen? Isn't 'T' the second character input into the buffer. Infact \n is the third character in the buffer. so why does \n get stored. correct me if iam wrong, but the buffer is released when \n is pressed or entered, then why is it again being stored in the next getchar() function.
Why is the first code executed differently then? I mean if i input "stackexchange" and hit enter "t" is stored as the second character as is wanted, but it in the second example if the same "st" is typed and "enter' is input, the "t" is not stored as the second input, but instead "enter' is taken as the second input.
I am sorry if my typing is confusing... basically i want to know the logical flow in both codes, how it happens behind the scene..

the only reason for storing \n is when you are entering S the pressing enter and not flushing out the carriage return so it will store \n in your second string.
firstInit = getchar() ;
will read and store S
lastInit = getchar() ;
will read and store carriage return
getchar() is a standard library function which will read a character from the console.

Check the below code which takes your input ST and stores it in 2 char's a and b.
int main(void){
char a;
char b;
a = getchar();
b= getchar();
printf("a = %c b = %c\n",a,b);
return 0;
}
Input
ST<enter>
Output
a = S b = T
If you are seeing a newline char being saved into b here then the input is like S<enter> not ST<enter>

Related

C: Nested do while loop not looping correctly

This code is supposed to -
Count the number of characters from input sequence.
Repeat the action until user exits the program.
Use nested do-while loop to achieve this purpose.
But the inner loop is executed only once.
Why?
#include <stdio.h>
int main ()
{
int x;
char i, ans;
i = '\0';
do
{
i = '\0';
x=0;
printf("\nEnter sequence of character:");
do
{
i = getchar();
x++;
}
while(i!='\n');
printf("\nNumber of characters entered is: %d", --x);
printf("\nMore sequences (Y/N) ?");
ans = getchar();
}
while(ans =='Y' || ans == 'y');
After you read the answer yes/no (the line with ans = getchar();), you'll read an "y" and a "\n". You'll consume the "y" and process it, but the next iteration when you read i = getchar();, i will consume the remaining "\n", so will break that do-while loop.
Although it's not my favourite solution, a simple workaround is this:
#include <stdio.h>
int main ()
{
int x;
char i, ans;
i = '\0';
do
{
i = '\0';
x=0;
printf("\nEnter sequence of character:");
do
{
i = getchar();
x++;
}
while(i!='\n');
printf("\nNumber of characters entered is: %d", --x);
printf("\nMore sequences (Y/N) ?");
ans = getchar();
getchar();
}
while(ans =='Y' || ans == 'y');
}
So just consume that extra "\n". This will work only if you type "y" followed by "\n" in terminal. If you type any extra characters, you'll have undefined behaviour.
Note: In your version, try to type: "y1234" then enter when prompted if you want to input again. You'll see that in fact the nested do-while loop works and will count the 4 characters after "y".
What happened:
getchar is a macro that gets a character from stdin.
The delimiter ('\n' in this case) is counted as a separate
character that remains in the buffer and is retrieved the next time
getchar() is called.
This causes inner loop to exit.
What could be done:
Insert the following after ans = getchar();
i = getchar();
if(i != '\n')
ungetc(i,stdin);
New code explained:
ungetc(int x,FILE *stream) pushes a character back into input stream.
stdin is the standard input stream defined in <stdio.h>.
We are reading a character and putting it back if it is not '\n'.
Not exactly sure, but I think that when the user presses enter to finish the 1st input character the input buffer keeps then enter button as the \n character. Try adding if(i == '\n') getChar(); after the x++;.

C programming - issues with printing string with backspace characters stored

I am writing a basic C program which takes a word from the user as input and prints that word twice on the same row. The issue that I am facing in printing the word twice is mentioned after the code that I have written below to do this job
void print_word()
{
char ch;
char str[15];
int i = 0; /* i will be used as index to access the elements of str */
printf ("\n Enter a word of your choice : ") ;
ch = getch() ; /* Dont echo character */
while ( !isspace(ch) && i < 14) /* while loop executes till user doesn't input a space or until the str array is full */
/* isspace() is defined in header file <ctype.h> */
{
putchar(ch); /* Now echo character */
str[i] = ch ;
i++ ;
ch = getch();
} //while loop ends
str[i] = '\0' ;
printf("\t") ; //print a gap
printf ("%s ", str) ;
printf ("%s", str) ;
}
This function works properly if user directly enters a word (without using backspace to edit the word).
Suppose user enters 'HELLO' then 5 characters viz.'H' 'E' 'L' 'L' 'O' gets stored in array str. But then user presses backspace three times and the word on the console appears 'HE' while str now contains eight characters H-E-L-L-O and 3 backspace characters. But when the printf function in the last two statements of this code is executed and prints str, the first statement correctly prints the 8 character and displays 'HE' on the console, but second statement prints 'HELLO', leaving the 3 backspace characters that are also there in the array str.
Why the last printf() statement is not printing the string str properly i.e., why is it not printing the backspace characters?
The problem remains even if I print str with puts() function or even if the str is printed with a for loop -- character by character. And I want to know what is actually happening in the backend process?
Use printf("%s\n", str); both times and you'll see that the first printf does not print 'HE'. It prints 'HELLO' just like the second one, just after that it moves the cursor back 3 times, so if you print both strings on the same line then the second string overwrites the last 3 characters of the first 'HELLO'. After printing HELLO and 3 backspaces you have output HELLO and cursor at the mark:
HELLO
^
After printing the space you have:
HE LO
^
After printing another HELLO and 3 backspaces:
HE HELLO
^
You might want to check this question if you want more information about printing strings with a backspace: Function printf() to print backspace problem.
As an alternative to printf("%s\n",str); solution you could process char by char your user's input.
Usually getch() is used whenever the programs require a full control of the input characters, so take advantage of it.
In your while loop just do this, instead:
while ( !isspace(ch) && i < 14)
{
putchar(ch); /* Now echo character */
if( ch == 0x08 && i > 0)
{
i--;
}
else
{
str[i] = ch ;
i++ ;
}
ch = getch();
}
Basically you need to check if the current input character is a backspace (ASCII value 0x08). If it is, decrease the current index of the input array in order to perform the character deletion. Of course don't do it if the current index is 0.
This approach is common in applications such as AT parsers.
This function works properly if user directly enters a word (without using backspace to edit the word).
See this,
#include<stdio.h>
#include<conio.h>
void print_word()
{
char ch;
char str[15];
int i = 0,flag=0;
printf ("\n Enter a word of your choice : ") ;
for(i=0; i<15&&flag==0; ++i)
{
ch = getch();
switch(ch)
{
case 13:
str[i] = '\0';
flag=1;
break;
case '\b':
if(i>0) i--;
str[i--]='\0';
printf("\b \b");
break;
default:
str[i] = ch;
printf("%c",ch);
}
}
str[15]='\0';
printf("\t") ;
printf ("%s ", str) ;
printf ("%s", str) ;
}
int main()
{
print_word();
}
You are responsible for removing backspace from str.
Why the last printf() statement is not printing the string str properly i.e., why is it not printing the backspace characters??
your input: HELLO+(3 backspace)
so the str contains {'H','E','L','L','O','\b','\b','\b'}
and the intersection point in console is
"HE^LLO"
After one tab (nearly 7 spaces), so console appears
"HE "
after one print of str
"HE HE^LLO"
after print of space and str
"HE HE HELLO"

fgets() keeps getting skipped before entering loop [duplicate]

This question already has an answer here:
fgets is getting skipped
(1 answer)
Closed 4 years ago.
Been trying to remove a character but the call to fgets gets skipped/jumped over. On different computers it runs like it should but for some reason, it skips and basically jumps to the end of the program. Any ideas?
Several problems in your code but I do not see any reason of fgets() skipped or jumped over. The getchar() function reads the next character from stdin. Generally when we give input to the getchar() function, we enter the character and press ENTER key. This left the \n character in input stream which can be consumed by next input function called. But in your case you are not calling any other input function after getchar().
[Try calling getchar() above fgets() and give input as - enter a character followed by ENTER key. You will see the fgets() is skipped because it consumes the leftover \n character from input stream stdin.]
Problem 1:
Look at this statement:
str[j] = str + 1;
Since, the str is a char array, str[j] represents a character at location j and str + 1 is pointer. So, this assignment is incompatible because you are trying to assign a char * type to a char. It should be:
str[j] = str[j + 1];
Problem 2:
Your code is having a logical problem. It is unable to handle the scenario where the character to be removed occurs consecutively in the input string. Test your code for input like "Hello World" [character l is occurring consecutively]. Your program output will be [after fixing problem 1]:
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Helo Word <==== character l not removed
Your program is unable to handle this particular scenario because once it removes a character, in the next iteration it starts with next character.
Problem 3:
The strlen() return type is size_t and you are using char type to receive its return value. Instead, you should use size_t type.
The getchar() return type is int [because it returns the special value EOF when the end of the input stream is reached]. You are using char type variable to receive getchar() return value.
One more point (it is not a problem but you should be aware of it and take the precautionary measures):
From fgets() [emphasis mine]:
Reads at most count - 1 characters from the given file stream and stores them in the character array pointed to by str. Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character. If no errors occur, writes a null character at the position immediately after the last character written to str.
So, it is possible that your input buffer passed to fgets() can have new line character ('\n') in it. For e.g., if you give input Hello World followed by ENTER key than the input buffer str will have "Hello World\n" in it. In your case this will not cause any problem but few extra iteration of loop. You can remove the \n from str buffer like this:
fgets(str, 100, stdin);
str[strcspn(str, "\n")] = 0; // This will remove the trailing newline character from input buffer
Also, you should check the fgets() return. In case of failure, fgets() returns NULL.
Putting these altogether, you can do:
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
size_t i, j, len;
int r;
printf("Enter a sentence: \n");
if (fgets(str, 100, stdin) == NULL) {
fprintf (stderr, ("fgets failed"));
return -1;
}
str[strcspn(str, "\n")] = 0;
printf("This is the sentence: %s\n", str);
printf("Enter character to remove: \n");
r = getchar();
/*If getchar returns EOF, no need to go through character removal logic*/
if (r != EOF) {
len = strlen(str);
i = 0;
while (str[i] != '\0') {
if (str[i] == (char)r) {
for (j = i; j < len; j++) {
str[j] = str[j+1];
}
len--;
}
else
i++;
}
}
printf("Sentence after removal: %s\n", str);
return 0;
}
Output:
# ./a.out
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Heo Word
# ./a.out
Enter a sentence:
zzzzz
This is the sentence: zzzzz
Enter character to remove:
z
Sentence after removal:
# ./a.out
Enter a sentence:
aazz
This is the sentence: aazz
Enter character to remove:
a
Sentence after removal: zz
Try changing r = getchar(); with scanf("%c\n", &r);.
Also, your loop has some bugs or inconsistencies:
You're assigning to str[j] the value of a pointer. Should be assigning to str[j] the value of str[j+1].
The end of the inner loop should be len-1 then.
j-- has no effect at all.
You should end your string with \0 after you're done, otherwise you'll print garbage (in my case it was a bunch of \ns).
Putting everything together:
for (i = 0; i < len; i++) {
if (str[i] == r) {
for (j = i; j < len-1; j++) {
str[j] = str[j+1];
}
len--;
}
}
str[len] = '\0';
printf("Sentence after removal: %s\n", str);
If you want to remove the \n at the end of the string after you read it, you can do
str[len] = '\0';
len--;
before the loop.

Code doesn't read the last character of string of Characters (C language)

#include "stdio.h"
int main() {
char input[10];
char standart;
int i;
int b = 0;
scanf("%c", &standart);
for(i = 0; i < 10; i++){
scanf("%c ", &input[i]);
if(input[i] == standart){
b++;
}
}
printf("%d", b);
return 0;
}
// ( 2 % a b ( r ) ? ( (
The code is suppost to read the first character in the list, then see how many of said characters there are (not including itself). But the code doesn't read the last character, in short when I input the sample input the code only sees 2 '(' while it should see 3.
You have to do it like this scanf(" %c",&c);
Because it reads '\n' from previous input, so the space will skip the '\n'
For the given input ( 2 % a b ( r ) ? ( (, the program takes the first character ( as input to variable standart -
scanf("%c", &standart);
The problem is occurring because in the first iteration of for loop the scanf was reading the first whitespace character (a blank space) from given input that exists after ( and storing it into input[0].
The for loop runs for 10 iterations and the last character ( is not inserted in the input array because of which the standart character count in input array is coming one less than expected i.e. 2.
Change the for loop scanf statement to -
scanf(" %c", &input[i]); //Removed the space after %c and added a space before %c.
With this, the for loop scanf will eat whitespaces characters.
So, the next character from input - 2 will be stored to input[0] and % will be stored to input[1] and so on and the last character '(' will be stored to input[9].
And the b will have the correct standart character count in input array i.e. 3.

Why this getchar() doesn't work properly? [duplicate]

This question already has answers here:
getchar() skips every other char in C
(2 answers)
Closed 7 years ago.
Can anybody tell me why the line o = getchar(); works properly only the first time and then once works, once it's not?
#include <stdio.h>
int main(void)
{
char o;
for (int i = 1; i > 0; i++)
{
printf("%d\n", i);
if (i % 10 == 0)
{
printf("Do you want to continue? (y/n): ");
o = getchar();
if (o == 'n')
break;
}
}
return 0;
}
First of all, getchar() returns an int, which may not fit into a char. Change
char o;
to
int o = 0;
Then, to come to the point of the skipping, well, it actually do not skip. When you press any key and press ENTER, the newline from the press of the ENTER key serves as the feed to the getchar() in every second iteration of the loop.
As Sourav Ghosh stated, the problem is the newline character. Once you type something in the console and press "Enter" afterwards, the text is in the input buffer. This buffer is then read by getchar. However, getchar only reads one character with each call. The problem is, that "Enter" is interpreted as a character ('\n') and is hold in the buffer, getchar is going to read it as an individual character. The next call of getchar will read the newline character, rather than the wanted character.
Solution: You could call getchar (after your actual call) until the newline is reached, thus clearing the read line inside the buffer.
while (getchar() != '\n')
;
Or just build a little function
int nextch() {
int ch = getchar();
while (getchar() != '\n')
;
return ch;
}

Resources