for loop runs twice in C - c

I am new to C programming. And I was doing a practice, and the question goes like this: Use the ?: operator and the for statement to write a program that keeps taking the characters entered by the user until the character q is accounted.
And here is the program I wrote:
#include <stdio.h>
main()
{
int x, i=0;
for (x = 0; x == 'q'? 0 : 1; printf("Loop %d is finished\n",i))
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
x=getc(stdin);
putc(x,stdout);
++i;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
The problem is: every time I enter a "non-q" character, the loop seems to run twice.
I don't know what is wrong with my program.
Please help!

When you enter a non-q letter, you also hit Enter, which is read in the second loop.
To make the loop only run once per input, use fgets() to read an entire line of input at once, and check if the input string matches your expectations.

When you type a and then press Enter, the newline character becomes part of the stdin stream. After a is read, the next time you execute x=getc(stdin), the value of x is set to \n. That's why two iterations of the loop get executed.

The loop runs twice because when you enter a non-q character, you actually enter two characters - the non-q character and the newline '\n' character. x = getc(stdin); reads the non-q character from the stdin stream but the newline is still lying in the buffer of stdin which is read in the next getc call.
You should use fgets to read a line from the stream as others have suggested and then you can process the line. Also, you should specify the return type of main as int. I suggest the following changes -
#include <stdio.h>
int main(void)
{
int x, i = 0;
// array to store the input line
// assuming that the max length of
// the line is 10. +1 is for the
// terminating null added by fscanf to
// mark the end of the string
char line[10 + 1];
for (x = 0; x == 'q'? 0 : 1; printf("Loop %d is finished\n", i))
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
// fgets reads an input line of at most
// one less than sizeof line, i.e.,
// 10 characters from stdin and saves it
// in the array line and then adds a
// terminating null byte
fgets(line, sizeof line, stdin);
// assign the first character of line to x
x = line[0];
putc(x, stdout);
++i;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}

When you enter a character, say 'x' and press enter, you actually input two characters, which are 'x' and '\n' also known as newline(when you hit enter). The '\n' becomes part of the input stream and the loop is executed for it as well.
Also, try inputting "xyz" and hit enter, the loop will be executed 4 times. For each 'x', 'y', 'z', and '\n'.
If you want the code to work one time for every input, use the function gets.
#include <stdio.h>
main()
{
int i=0;
char x[10];
for ( ; x[0]!='q'; printf("Loop %d is finished\n",i) )
{
printf("Enter q to exit!!!\n");
printf("Please enter a character:\n");
gets(x);
i++;
}
printf("\nThe for loop is ended. Bye!");
return 0;
}
In this code we declared x as an string, the gets() function reads the whole line we entered, then in the condition part of the for loop, we check whether the first character of the string is 'q' or not.

Related

Why does program terminate without taking input?

This is sample of my program:
#include <stdio.h>
void sum();
int main()
{
char choice[4];
do
{
sum();
printf("\nDo You want to restart the program: yes or no:\n");
fgets(choice, 4, stdin); //error point
} while (choice[0] == 'y' || choice[0] == 'Y');
printf("\nThanking You");
return 0;
}
void sum()
{
int a = 3, b = 4;
printf("sum of two number is %d", a + b);
}
In this program, only in the 1st iteration of while does it ask for input in choice and, on the next iteration the program auto terminates by taking any value in choice.
Following is the result after execution of code:
sum of two number is 7
Do You want to restart the program: yes or no:
yes
sum of two number is 7
Do You want to restart the program: yes or no:
Thanking You
[Program finished]
I am unable to understand that it takes input in choice while I haven't used scanf() (which leaves the new line character in the buffer). It may be it takes input from buffer that may be whitespace or other characters, but I don't know from where it came?
Your program is leaving a newline in the input buffer after the first prompt because there's not enough room for it in the buffer.
On the first call to fgets you give the string "yes" followed by a newline. The buffer has size 4 and you pass that size to fgets so it reads at most that many characters-1 to account for the terminating null byte. So there is still a newline left in the buffer.
That newline gets read immediately the next time fgets is called.
You should enlarge your buffer to handle more characters.
Your choice array is not large enough to hold all the input from the first loop. The second argument to the fgets function (4) tells it to read at most 3 characters (and it then appends a nul-terminator to the input). So, it leaves the newline character in the input stream, and that is read in the second loop (by itself).
Just increase your choice array size and the input limit to 5 (or more):
#include <stdio.h>
void sum();
int main()
{
char choice[5]; // Increase space for newline and nul
do {
sum();
printf("\nDo You want to restart the program: yes or no:\n");
fgets(choice, 5, stdin); // Inputs 'y', 'e', 's' and newline (4 chars) and appends a nul.
} while (choice[0] == 'y' || choice[0] == 'Y');
printf("\nThanking You");
return 0;
}
void sum()
{
int a = 3, b = 4;
printf("sum of two number is %d", a + b);
}
From fgets - cppreference (bolding 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
a newline character is found, in which case str will contain that
newline character, or if end-of-file occurs. If bytes are read and no
errors occur, writes a null character at the position immediately
after the last character written to str.

How to to stop accepting input once the user presses ENTER? C programming language

I'm a first year CS student and I tried writing code from a given prompt. This is the prompt:
Write a program that:
creates char array array_1 of length 10.
creates char array array_2 of length 10, and
stop receiving input into array_1 and array_2 when the user hits ENTER and
insert a null character into the array.
My code:
#include <stdio.h>
int main(void)
{
char array_1[10];
printf("Enter a character in array_1 (Press ENTER to stop):\n");
do {
scanf("%c", &array_1[10]);
}
while(array_1[10] != '\n');
printf("\\0 \n");
char array_2[10];
printf("Enter a character in array_2 (Press ENTER to stop):\n");
do {
scanf("%c", &array_1[10]);
}
while(array_1[10]!='\n');
printf("\\0 \n");
return 0;
}
Expanding on Some programmer dudes' comment. a better approach to your problem would definitely be using fgets() instead of scanf().
Here's an updated solution to your problem.
#include <stdio.h>
int main(void)
{
char array_1[10];
printf("Enter a character in array_1 (Press ENTER to stop):\n");
//Replacing the whole do while loop
fgets(array_1, sizeof array_1, stdin);
printf("\\0 \n");
char array_2[10];
printf("Enter a character in array_2 (Press ENTER to stop):\n");
//Replacing the whole do while loop
fgets(array_2, sizeof array_2, stdin);
printf("\\0 \n");
return 0;
}
In accordance with the community guidelines on homework questions, I will not provide a full solution to the problem, but I will provide the following:
You are writing every character that you read from standard input to array_1[10]. Since array indexes are zero-based, you are always writing to the 11th element of the array, which does not even exist, as the array has a size of 10.
You should instead write the first character to the first element of the array, which is array_1[0], then, if the first character is not a newline character, write the second character to the second element of the array, which is array_1[1], etc. This can be accomplished with a for loop using a loop counter variable, for example like this:
int i;
//Limiting the loop to 9 iterations will prevent a buffer overflow.
//We are not doing 10 iterations, because the buffer only has space
//for 9 characters (10 characters if you include the terminating
//null character).
for ( i = 0; i < 9; i++ )
{
//attempt to read next character and break loop prematurely if
//an error occurs
if ( scanf("%c", &array_1[i]) != 1 )
break;
//break loop prematurely if user entered newline character
if ( array_1[i] == '\n' )
{
//the following line is necessary unless you want the
//newline character to be overwritten by the terminating
//null character, which effectively discards the newline
//character (this may be desirable)
i++;
break;
}
}
//add terminating null character
array_1[i] = '\0';

Program seems to be ignoring one instance of 'gets()' and show an error message when the user hasn't interacted with the program [duplicate]

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
int n=1,i,cont;
char string[50];
scanf("%d",&n);
while(n!=0){
gets(string);
cont=0;
for(i=0;i<strlen(string);i++){
if(string[i]=='.'){
cont++;
}
}
if(cont%2==0){
printf("S\n");
}else{
printf("N\n");
}
scanf("%d",&n);
}
return 0;
}
My problem is quite simple but troublesome, I want to read an integer value n, and then read a string, after that read n again, but whenever I run the program, it only reads the string value... but if I digit 0 the program ends... it's like my scanf is within the gets function.
Mixing scanf with gets or fgets is troublesome because they each handle newlines differently.
Get rid of the gets call (which is unsafe anyway) and replace it with the following scanf call:
scanf("%49s", string);
This will read at most 49 characters into string (i.e. one less that its size).
From OP's comments, it sounds like the goal is to be able to read strings containing spaces. While there are ways to accomplish this using scanf(), it would be better to use fgets(), which is at the least less error-prone.
The fgets() function can be used to read input for the number into a buffer, and this buffer can then be processed by sscanf() to extract the number. Since fgets() keeps the newline character, it is not left behind to interfere with the next I/O operation.
But, when fgets() is used to get the string, since the newline is retained, it may be desirable to remove it. This can be accomplished in a number of ways, but here strcspn() is used to provide the index of the first \r or \n character encountered; a \0 character is then written to this location, removing the terminating newline from the string.
The code below illustrates these suggestions. Note that both buffer[] and string[] are generously allocated to accommodate reasonably large inputs. If a user enters a large number of characters (more than 999 in this case), the extra characters are left behind in the input stream for the next I/O function call. Also note that the main loop has been streamlined a bit; now there is a for(;;) loop that never terminates, broken out of when the user enters 0 for the number. And, there is a nested loop within the main loop that prompts the user to enter a number until a valid number is entered. Since the #include <stdlib.h> was unnecessary, it was removed. Better code would check the values returned from the calls to fgets() for possible errors.
#include<stdio.h>
#include<string.h>
int main(void)
{
int n = 1, cont;
char buffer[1000];
char string[1000];
for (;;) {
/* Loop until user enters a number */
do {
printf("Please enter a number: ");
fgets(buffer, sizeof buffer, stdin);
} while (sscanf(buffer, "%d", &n) != 1);
/* Break on 0 */
if (n == 0) break;
/* Get a string, and remove trailing newline */
printf("Please enter a string\n");
fgets(string, sizeof string, stdin);
string[strcspn(string, "\r\n")] = '\0';
cont = 0;
for (size_t i = 0; i < strlen(string); i++) {
if (string[i] == '.') {
cont++;
}
}
if (cont % 2 == 0){
printf("S\n");
} else {
printf("N\n");
}
}
return 0;
}
When you enter 5 for an example, you hit a new line character afterwards.
So you are entering 2 characters: 5 and a new line character.
That new line character is causing your headache.
The new line character is also considered an input.
In order to ignore this new line char, simply add a new line that acts as a garbage collection:
char garbage[50];
scanf( "%d", &n);
fgets(garbage, sizeof(garbage), stdin);

Program to replace a letter with another in C

I wrote a program to replace a letter in a string. Although it has no error, the output is not as expected. Please help me with it.
#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
void replace(char s,char d);
char a[100];
int main()
{
char b,r;
printf("enter the string\n:");
gets(a);
printf("enter the the letter to be replaced\n:");
scanf("%c", &b);
printf("enter the letter to be replaced with\n:");
scanf("%c", &r);
replace(b,r);
}
void replace(char s, char d)
{
int i,f=0;
for (i = 0; a[i] != '\0'; i++)
{
if (a[i] == s)
{
a[i] = d;
f = 1;
}
}
if (f == 0)
{
printf("letter not found");
}
}
Output
enter the string
:hello every one
enter the the letter to be replaced
:e
enter the letter to be replaced with
:letter not found
I wanted to replace e with o but I am not able to give the input for word to be replaced
UPDATE
Use this loop to get rid of the input buffer problem when using scanf
but I am not sure how to implement it on my program need help
void
clear(void)
{
while ( getchar() != '\n' )
;
}
The scanf() function skips over initial whitespace characters when you read in strings using the %s specifier, but it does not do this when your read chars with the %c specifier. The gets() function that you use (which you should never ever ever use ever) reads through the newline, and discards it. So your first call to scanf() has a clean input stream. When you call scanf() the first time, a value is read into the variable b, but the trailing newline is left behind in the input stream. Then, when you try to read the next value, scanf() picks up this newline, instead of the value that you want to enter.
One fix for this is to discard any unwanted characters from the input stream like this:
while (getchar() != '\n')
continue; // discard unwanted characters
You can also test for the EOF character in the conditional expression if you really want to be careful. One virtue of this approach is that, no matter how many characters the user enters at your second prompt, only the first is taken, and the remaining characters through the newline are discarded. Since there is nothing left in the input stream, scanf() has to wait for the user to enter something at your third prompt. You should place this code after each call to scanf() to make sure that the input stream is clear.
Now, gets() is a terrible and unsafe function begging for buffer overflows, because it doesn't check to see if there is enough memory allocated for the string it is getting. Instead, use fgets(). This function takes an argument that specifies the maximum number of characters to read, including the null-terminator. fgets() also reads the newline character into the string, so you have to dispose of that yourself if you don't want it. Here are the modifications you need to make:
int i = 0;
...
char b,r;
printf("enter the string\n:");
fgets(a, 100, stdin);
while(a[i] != '\n' && a[i] != '\0') // remove newline
++i;
a[i] = '\0';
printf("enter the the letter to be replaced\n:");
scanf("%c", &b);
while (getchar() != '\n')
continue; // discard unwanted characters
printf("enter the letter to be replaced with\n:");
scanf("%c", &r);
while (getchar() != '\n')
continue; // discard unwanted characters
replace(b,r);
printf("%s\n", a);
...
I added a final printf() to display the changed string.

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;
}

Resources