Count lowercase letters till the input is string - c

I wrote a short code in C which count the lowercase letters (only letters) and it'll stop working when I enter a number or something else. Here is the code:
char letter;
int num=0;
do
if(islower(letter = getchar()))
num++;
while(isalpha(letter));
printf("%d", num);
return 0;
My problem is that it isn't working properly (only print "1" as result).
And it has to be stopped when the next character isn't alphabetical letter. Not sure that part is right.
Any idea what did I wrong? Thanks.

what's about this?
char letter;
int num=0;
while (isalpha(letter = getchar())) {
if (islower(letter)) num++;
}
printf("%d", num);
return 0;
And it has to be stopped when the next character isn't alphabetical letter.
keyboard input can be buffered - not processing until Enter be pressed
only print "1" as result
can you write some examples of inputed in console caused to "1" output?

The problem is that, after inputting a single character, the subsequent call to getchar() returns a newline character, as the '\n' from the return key is buffered. So, the first iteration of
do
if (islower(letter = getchar()))
num++;
while (isalpha(letter));
works, but the program displays "1" as the islower() call returns false when the newline is processed.
To fix this, use a while loop to eat away the extra newlines. You could do it as such:
do {
while ((letter = getchar()) == '\n')
;
if (islower(letter))
num++;
} while (isalpha(letter));

Related

Undefined behaviour of scanf() in a do-while loop

I'm currently learning C by a book "C Programming a modern approach" and encountered this code. When I tried to run it, after typing consecutive characters like 'abc' and hitting Enter (new line), nothing was printed. Please explain what is going on here.
char ch;
do {
scanf("%c" , &ch);
} while (ch != '\n');
printf("%c", ch);
You're asking the user to input a character using scanf. This is happening in a loop until the user inputs a '\n' or newline character (the same as pressing the enter key), which is when the loop will break.
Your print statement will then print the character in the variable ch, which at that point will be '\n' (since this variable just stores one character, the last one you typed).
This newline character will probably be invisible when you run your program so you may not be seeing it. You can add another print statement after the loop and if that print statement starts at a newline, you know that the '\n' was printed on the previous line.
Something like:
#include <stdio.h>
int main()
{
char ch;
do
{
scanf("%c" , &ch);
} while (ch != '\n');
printf("%c", ch);
printf("I should show up on a newline");
return 0;
}
The code you provided reads characters from the input using the scanf() function and stores them in the variable ch until a newline character (\n) is encountered. After that, the program prints the last character that was read, which is the newline character.
The reason you are not seeing any output when you enter characters followed by a newline character is because the printf() statement is only executed after the loop has finished running. So, the program is waiting for you to enter a newline character to terminate the loop and print the last character that was read.
If you want to see the characters you enter, you can add a printf() statement inside the loop, like this:
char ch;
do {
scanf("%c" , &ch);
printf("%c", ch);
} while (ch != '\n');
This will print out each character as it is read from the input, so you can see what you're typing. Happy coding :)
When I tried to run it, after typing consecutive characters like abc and hitting Enter (new line), nothing was printed.
Well with the posted code, if the loop even finishes, the last byte read by scanf("%c", &ch) and stored into ch is the newline character. Hence printf("%c", ch) outputs this newline and it seems nothing is printed but something is, the newline which is invisible on the terminal but does move the cursor to the next line.
You can make this more explicit by changing the printf call to this:
printf("last value: '%c'\n", ch);
Note however that the posted code is not a recommended way to read the contents of the input stream:
scanf("%c", &ch) may fail to read a byte if the stream is at end of file. Failure to test this condition leads to undefined behavior (ch is unmodified, hence stays uninitialized if the input stream is an empty file) or to an infinite loop as ch may never receive a newline.
this code is a typical example of a do / while with a classic bug. It would be much better to write the code using getchar() and a while loop.
Here is a modified version:
#include <stdio.h>
int main(void) {
int c; // must use int to distinguish EOF from all valid byte values
int count = 0; // to tell whether a byte was read at all
char ch = 0; // the last byte read
// read all bytes from the input stream until end of file or a newline
while ((c = getchar()) != EOF && c != '\n') {
ch = (char)c;
count++;
}
if (count == 0) {
printf("no characters entered: ");
if (c == EOF) {
printf("end of file or read error\n");
} else {
printf("empty line\n");
}
} else {
printf("last character on line is '%c'\n", ch);
if (c == EOF) {
printf("end of file or input error encountered\n");
}
}
return 0;
}

Strange 10 value gets printed when I print inputed characters by their ASCII decimal code

#include <stdio.h>
#include <stdlib.h>
int main()
{
int end;
while(( end = getchar() ) != EOF ){
printf("%d\n",end);
}
system("pause");
return 0;
}
I want to print the ASCII codes of characters with this code but whenever I run the code after it gets the char from me it prints its ASCII equivalent with decimal 10. For example if I run the code and pass "a", it will print 97 and 10. Why does it print 10, this happens with all other characters too.
Thank you for answers and as a followup question when I add a counter after I input a character counter's value increases by two, why does this happen
#include <stdio.h>
#include <stdlib.h>
int main()
{
int end;
int count=0;
while(( end = getchar() ) != EOF ){
printf("%d\n",end);
count++;
printf("counter is now %d\n",count);
}
system("pause");
return 0;
}
As stated you are printing the ASCII decimal codes for 'a' and '\n' respectively, this is because, in your code, getchar reads all the characters in the stdin buffer, including the newline character which is present because you press Enter.
You can avoid this by simply making it be ignored by your condition:
while((end = getchar()) != EOF && end != '\n'){
printf("%d\n", end);
}
Disclaimer: David Ranieri added a comment with the exact same solution as I was writing my answer (which he kindly deleted) so credit to him as well.
Regarding your comment question and the question edit:
If you don't want the '\n' to interrupt your parsing cycle, you can simply place the condition inside it.
while((end = getchar()) != EOF){
if(end != '\n'){ //now as '\n' is ignored, the counter increases by one
printf("%d\n", end);
count++;
printf("counter is now %d\n",count);
}
}
The reason why the counter is increased by two is, again, because two characters are parsed, whatever character you input and the newline character. As you can see in the sample, if you ignore the '\n', the counter will only increase by one, provided that you only enter one character at a time.
In ASCII, a newline is represented by the value 10.
Anytime you type a sequence of characters and press the ENTER key, you get the ASCII values for the letters/numbers/symbols you types as well as the value 10 for the newline.

while(scanf) is infinite looping?

The code is supposed to accept a line of user input containing different characters and then print out one line containing only the letters. For example, Cat8h08er64832&*^ine would be Catherine. However, the code works and outputs "Catherine" however the program doesn't exit... see picture here I'm not sure if the loop is just looping infinitely or...
int main(void){
int i=0, j=0;
char userString[1000];
char alphabet[1000];
printf("Please enter a string: ");
while(scanf("%c", &userString[i])){
if((userString[i]>='A' && userString[i]<='Z')||(userString[i]>='a'&&userString[i]<='z')){
alphabet[j]=userString[i];
printf("%c", alphabet[j]);
j++;
}
i++;
}
printf("\n");
return 0;
}
Your problem is that you're checking that scanf is finished by checking for the return value 0. scanf returns EOF (usually, -1) when there is no more input. So if you get some input (return 1) then no more input (return -1), your loop won't ever exit.
Change the scanf condition to check for <> EOF.
This answer also explains it quite well.

Putchar and Getchar in C

I'm reading K&R's The C Programming Language and have become confused on putchar and getchar. I made a program where you enter 10 chars and the program prints them back out to the screen.
#include <stdio.h>
int main()
{
int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
putchar(ch);
}
return 0;
}
I expected to get an output like this:
Enter a single character >> a
a
Enter a single character >> b
b
...and so on 10 times but this is the output I got: (I stopped after entering 2 chars)
Enter a single character >> a
aEnter a single character >>
Enter a single character >> b
bEnter a single character >>
Enter a single character >>
not sure why my input character is being combined with the fixed string and being output.
Also, I'm not too sure why ints are used to store characters.
putchar(ch);
just prints single character and the following printf continues within the same line. Simply add:
putchar('\n');
right after putchar(ch);, which will explicitly start the new line before the printf is executed. Additionally you should also take '\n' from the input which stays there after you enter the character:
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
getchar(); // <-- "eat" new-line character
putchar(ch);
putchar('\n'); // <-- start new line
}
You are not printing a new line. After putchar(ch); you should use putchar('\n'); to print a new line.
User terminal can operate in canonical and non-canonical modes. By default it operates in canonical mode and this means that standard input is available to a program line-by-line (not symbol-by-symbol). In question user inputs something (let it be letter 'a', 0x61 in hex) and pushes enter (new line character '0x0A' in hex). Ascii table is here. So this action gives a two symbols to a program. As mentioned in man getchar() reads it symbol-by-symbol. So loop iterates twice for one character. To see what is going on use the following program (+loop counter output, +character code output):
#include <stdio.h>
#include <unistd.h>
int main()
{
int i;
char ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character %d >>", i);
ch = getchar();
printf("Ch=0x%08X\n", ch);
/*putchar(ch);*/
}
return 0;
}
Output:
┌─(02:01:16)─(michael#lorry)─(~/tmp/getchar)
└─► gcc -o main main.c; ./main
Enter a single character 0 >>a
Ch=0x00000061
Enter a single character 1 >>Ch=0x0000000A
Enter a single character 2 >>b
Ch=0x00000062
Enter a single character 3 >>Ch=0x0000000A
Enter a single character 4 >>^C
So program gets two symbols and prints them. And new line symbol is not visible. So in the question user see one strange additional line.
Detailed description on different terminal modes and how to make its adjustments can be found here.
Also stty utility can be useful while working with terminal options ("icanon" tells if terminal use canonical mode or not).
And about storing chars as int in getchar() output - see my answer for similar topic.
The term on which our focus should be on, is "Stream".
A "Stream" is a like a bridge, responsible for flow of data in a sequential way. (The harmony of smooth streaming, both in and out of a program, is managed by libraries/header files, e.g. stdio.h)
Coming back to your question :
When you type input as 'a' and hit 'enter', you supply 2 values to input stream.
- a (ASCII Value : 97)
- enter (ASCII Value : 13)
/*This 'enter' as an input is the devil. To keep it simple, i will keep calling it
as Enter below, and the enter is usually not displayed on screen*/
NOTE/IMPORTANT/CAUTION before proceeding: Till the time your stream doesn't get completely empty, you can't write new characters from the console into the stream. (This scenario only implies for the use of getchar and putchar, as shown below)
HERE IS YOUR CODE:
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
putchar(ch);
}
Loop Pass 1 :
a) You ask user to enter a character. // printf statement
b) getchar reads only a single character from stream.
c) putchar renders/displays only a single character from stream.
d) At first pass you provide input as 'a' but you also hit 'Enter'
e) Now, your stream is like a ***QUEUE***, at first pass, and at 1st place of
the queue, you have 'a' and at 2nd place 'enter'.
f) Once you do putchar, the first character , i.e. 'a' from the stream/queue
gets displayed.
e) Loop ends.
g) Output of this pass:
Enter a single character >>a
Loop Pass 2 :
a) You ask user to enter a character. // printf() statement
b) Unfortunately your stream isn't empty. It has an "enter" value from the
previous pass.
c) So, getchar(), reads the next single character, i.e. 'enter' from stream.
(This is where you were expecting to manually enter the next character,
but the system did it for you. Read the NOTE/IMPORTANT/CAUTION section
mentioned above)
d) putchar() displays 'enter' on screen, but since 'enter' is no displayable
thing, nothing gets displayed.
e) Output of this pass:
Enter a single character >>
Loop Pass 3 :
Similar as loop 1, only input this time is 'b'.
Loop Pass 4:
Similar as loop 2
and so on till 10 passes. (So, last character you will be able to enter is 'e'.)
INFERENCE/CONCLUSION:
So, long story short, you were expecting to enter the next character,
so that getchar would pick your entered value, but since from your
previous pass,'enter' value was already waiting in the stream,
it got displayed first, giving you such an illusion.
Thank you.
Let me know if your thoughts are different.
Loop on the even number of time, getchar() is not taking input from keyboard, but it is taken from the previous entered hit, so you would have also noticed that loop is only executed 5 times. So you have to clear the buffer, i.e. pressed entered, so that new character can be entered in the ch.
for (i = 0; i < 5; i++)
{
printf("\nEnter a single character >> "); // new line
ch = getchar();
while (getchar() != '\n'); //Clearung buffer.
putchar(ch);
}
Not sure if ideal, but this worked:
#include <stdio.h>
int main()
{
int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
getchar();
ch=getchar();
putchar(ch);
}
return 0;
}
I am a beginner . I tried this version of code and it gave the desired output.
#include <stdio.h>
int main()
{
int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
fflush(stdin);
ch = getchar();
putchar(ch);
printf("\n");
}
return 0;
}
Although getchar() gets a single character, control isn’t returned to your program until the user presses Enter. The getchar() function actually instructs C to accept input into a buffer, which is a memory area reserved for input. The buffer isn’t released until the user presses Enter, and then the buffer’s contents are released a character at a time. This means two things. One, the user can press the Backspace key to correct bad character input, as long as he or she hasn’t pressed Enter. Two, the Enter keypress is left on the input buffer if you don’t get rid of it.to Get rid of the Enter keypress insert an extra getchar() that captures the Enter but doesn’t do anything with it.so you just need an extra getchar() after ch = getchar();like this
#include <stdio.h>
#include <stdlib.h>
int main()
{ int i;
int ch;
for(i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
getchar();
putchar(ch);
}
return 0;
}
I managed to get the desired result. I added a newline character and getchar() which picks up the extra character.
#include <stdio.h>
int main()
{
int i;
char ch;
for (i = 0; i < 10; i++)
{
printf("Enter a single character >> ");
ch = getchar();
putchar(ch);
putchar('\n');
getchar();
}
return 0;
}

Why wont my input from scanf print correctly?

My program scans from input and prints all the capital letters used.
Im trying to print the original input from stdin at the end of my program too.
But when i use printf, it seems to skip the first part of the input expression, printing the remaining stuff in my character array. Please help me see where the problem lies. -comments in code-
#include <stdio.h>
int main(void){
char input[81];
int letters[91];
int i;
//initialize arrays input and letters
for (i = 0; i < 90; i++) letters[i] = 2;
for (i = 0 ; i < 80; i++) input[i] = 'a';
i = 0;
//reads into input array until EOF
while((scanf("%c",input)!= EOF)){
//checks input for characters A-Z
if((input[i]>= 'A' && input[i]<= 'Z'))
letters[input[i]] = 1;
}
//prints capital letters from input that occur at least once
for(i = 'A'; i < 'Z'; i++){
if (letters[i]==1)
printf("%c", i);} // this output works fine, the scan worked??
//print blank line
printf("\n\n");
// print input
printf("%s\n", input); //This is where the incorrect output comes from.
return 0;}
does my original input change? why?
did my input not get scanned correctly in the first place?
please respond quickly!
Here:
while((scanf("%c",input)!= EOF)){
you're only ever reading characters into input[0]. This is fine for what you're doing for letters, but obviously when you try to print out input, it's not going to work as you expect.
When you fix it, you'll also need to remember to add a terminating \0 after the last input character.
The scanf loop reads your input one character at a time, and stores that one character in input[0]. When the scanf loop is completely finished, input[0] contains the last character read, and the rest of input is untouched.
To repair, you need to include i++ at the end of the scanf loop.
By the way, it would be clearer (and more efficient) to fill the input buffer with a single call to fgets then loop through the input buffer with: for (i=0; buf[i]!='\0'; i++) { ... }
You must do
while((scanf("%c",&input[i])!= EOF))
{i++;}
instead of this
while((scanf("%c",&input)!= EOF))
{}
What you are doing is scan the character into the address of the first element int the array everytime, hence it gets overwritten again and again. Remaining part of the input[] array is not being accessed, and hence does not change

Resources