While loop printing twice during one loop - c

So I have this little while loop which seems to print out my text twice during one run.
So here is the code:
int main(void){
char cont;
int check = 1;
while(check == 1){
printf("Something");
cont = getchar();
if(cont == 'j')
check = 1;
}
}
Now the output of this is:
Something, now it waits for input
Something, Something and waits for input.
After the first print, it will print twice when I press j.
Why is that?

You press 'j' and the 'newline', so you typed two chars and loop executes twice before starting to read next line.

Your code is stuck in loop because you test check==1 and check is always 1
you can make else part
if(cont == 'j')
check = 1;
else
check =0;

It is an infinite loop. Always recheck your program.
Maybe you wanted
if(cont == 'j')
check = 0;

Related

2 while loops in a function in C

Is it possible to run 2 while loops in the same function?
Only one of the while loops works. If I remove the first the one, the second one will work and if I remove the second one, the first one will work.
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "results.txt"
void analyseText(int character[], int i, FILE *fptr, int *sum, int a)
{
while ((i = fgetc(fptr)) != EOF)
{
if (i >= 'a' && i <= 'z')
character[(i - 'a')]++;
if (i >= 'A' && i <= 'Z')
character[(i - 'A')]++;
for (int i = 0; i < 26; i++)
{
printf("%c: %d\n", i + 'a', character[i]);
}
while (1)
{
int result = fscanf(fptr, "%d", &a);
if (result == EOF) {
break;
}
else if (result == 1) {
*sum += a;
}
else {
fscanf(fptr, "%*c");
}
}
}
}
I've ran your program and it seems the second while loop terminates the function. The second while loop will read the characters from the file and will do so until it reach the end, then will exit. Both while loop executes, but the first one executes only once and the second executes till will reach the end of the file. Maybe it is a logic bug there?
Also, are you trying to read some numbers in the second loop, the result will never pe 1 if there are only characters in the file.
You have an (almost) infinite loop inside an (almost) infinite loop, with just about the same stop condition for both.
One of them will run "forever" and when it triggers the stop condition the other will also stop, giving the appearance of just one of the loops running.
2 loops
enter infinite loop1
do some stuff one once
enter infinite loop2
do some stuff two "forever"
when you remove the inner loop
enter infinite loop1
do some stuff one "forever"
when you remove the outer loop
enter infinite loop2
do some stuff two "forever"

Why this weird infinite loop occuring?

I'm writing a arduino serial communication code where I'll send sentence through serial communication like "azyb"+sentence+"byza" where first and second part is to identify my sentence is going to begin and end . My code is here (just giving the loop function as other's working fine) :
void loop()
{
if (Serial.available() > 0)
{
int i=0, j=0, len=0;
char *sentance;
String line = Serial.readString();
len = line.length();
Serial.println(len);
Serial.println(line);
for (; i < len; i++)
if (line[i] == 'a' && line[i+1] == 'z' && line[i+2] == 'y' && line[i+3] == 'b'){
//first if
Serial.println("First");
i += 4;
while (i < len){
sentance[j] = line[i];
i++; j++;
if (line[i+1] == 'b' && line[i+2] == 'y' && line[i+3] == 'z' && line[i+4] == 'a'){
// second IF
Serial.println("Second");
sentance[j] = 'NULL';
encry_flag = true;
i = i + 4;
line = "";
break;
}
}
}
if (!encry_flag){
Serial.println("No code is send");
Write_text("damn "); // to write text in OLED display
}
else{
Serial.println(sentance);
Write_text(sentance); // to disply sentence in OLED display
encry_flag = false;
}
// clear the buffer
while (Serial.available() > 0)
char c= Serial.read();
}
}
But when I send a valid sentence like "azybanklonbyza" which will display "anklon" in OLED display , the code get trapped into a infinite loop which goes till first if condition came true but never run till the second if condition came true,and then circle back which should not be acting like this.
this infinite loop do not check the condition either encry_flag is true or false and never goes to the statement where buffer is being cleared.
From the screenshot you can understand that the for loop and the while loop within the for loop breaks as total strings is printed again and again which is done only once before for loop.
From where this infinite loop is created ? I'm totally lost.
FYI : if "azyb" and "byza" is not added at the beginning and end , the code ran just fine as it never fulfill any if condition. I tried using one character also ( "azybhbyza" to print "h" ) , but the result is same .
I am not familiar with arduino but
if (line[i+1] == 'b' && line[i+2] == 'y' && line[i+3] == 'z' && line[i+4] == 'a')
Should it not start with i ? And I see you used a character pointer "sentance" but you have not initialized it anywhere and as far as I know. The uninitialized pointer might lead to memory corruption depending on compiler memory management. Depending on hardware memory I am also considering the fact that it may corrupt some other memory contents also. Which may explain your variable "i" not reaching the end. Try initializing sentance with some space like
sentance = new char[25];
It may work. And also if you are testing on hardware, it may behave freaky at times.

Error check for character when reading in integers in C

For my programming class I've written a program to calculate the sum of divisors. So I've gotten to my final part which is error checking, which I am having a problem with if I read a character in. I have searched on S.O. earlier,as well as tried to figure something out, and couldn't find a solution that works for endless negative numbers until 100.
When I hit a character it sets it to 0 and just goes to the end, where I want it to exit once it reads it in
int main (void){
int userIN=0;
int i = 0;
int next = 0;
int temp= 105;
int cycle;
puts("Enter up to 10 integers less than or equal to 100");
while(scanf("%d ", &userIN) !=EOF && (i < 10))
{
if(userIN > 100){
printf("Invalid Input\n");
exit(1);
}
else if(userIN < 100)
{
Thanks for the help in advance
EDIT: The program is cycling through correctly, My Issue is error checking for a character being entered not anything with the code itself
scanf() returns a value other than EOF if it cannot read the values specified by the format string (e.g. with %d, it encounters data like foo). You can check for that. The caveat is that it does not read the offending data from stdin, so it will still be there to affect the next call of scanf() - which can result in an infinite loop (scanf() reporting an error, call scanf() again, it encounters the same input so reports the same error).
You are probably better off reading a whole line of input, using fgets(). Then check the input manually or use sscanf() (note the additional s in the name). The advantage of such an approach is that it is easier to avoid an infinite loop on unexpected user input.
You could loop while i is less than 10. The first if will see if scanf failed. If so the input buffer is cleared and the while loop tries again. If EOF is captured, then exit. If scanf is successful, the input is compared to 100 and if in range, the while loop counter is incremented.
Declare int ch = 0;
while ( i < 10) {
printf("Enter %d of 10 integers. (less than or equal to 100)\n", i + 1);
if(scanf(" %d", &userIN) != 1)
{
while ( ( ch = getchar()) != '\n' && ch != EOF) {
//clear input buffer
}
if ( ch == EOF) {
exit ( 1);
}
}
else {
if(userIN > 100){
printf("Invalid Input\n");
}
else
{
i++;// good input advance to the next input
printf("Valid");
}
}
}

End while loop with ctrl+d, scanf?

I want the user to be asked "how many circles" they wanna write until the user decides to end it with (Ctrl+d) which is EOF?
extra question: if I write a letter for example "k" it will spam out circles. How do I change that?
#include <stdio.h>
int main ()
{
int i;
int x;
printf("\nHow many circles do you want to write?\n");
scanf("%d", &x);
while(x != EOF)
{
for (i = 1; i <= x; i = i + 1)
{
putchar('o');
}
printf("\nHow many circles do you want to write?"
"(to end program click ctrl+d at the same time!))\n");
scanf("%d", &x);
}
printf("\n\n Bye! \n\n");
return 0;
}
The biggest problem with your program is that scanf will not read an EOF into a variable. However, fixing just this problem is not going to make your program entirely correct, because there are other issues in your code:
Your code repeats itself - when possible, you should unify the code that deals with the first iteration vs. subsequent iterations.
Your code will not handle invalid input - when an end-user enters non-numeric data, your program goes into an infinite loop.
Your code follows the old style of C - declaring all variables at the top has not been required for more than fifteen years. You should declare your loop variable inside the loop.
Here is how you fix all these shortcomings:
int x;
for (;;) {
printf("\nHow many circles do you want to write? (to end the program click Ctrl+D at the same time!)\n");
int res = scanf("%d", &x);
if (res == EOF) break;
if (res == 1) {
... // Draw x circles here
} else {
printf("Invalid input is ignored.\n");
scanf("%*[^\n]");
}
}
printf("\n\n Bye! \n\n");
return 0;
As per the man page, scanf() will return EOF, not scan EOF to x as a value.
Return Value
These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.
The value EOF is returned if the end of input is reached before either the first successful conversion or a matching failure occurs......
Also,
if I write a letter for example "k" it will spam out circles, how do I change that?
In case of input of one char value, it causes matching failure, in your case, scanf() returns 0, instead of 1.
So, altogether, you've to collect the return value of scanf() and check check that value for the required condition. You can change your code as
int retval = 0;
while ((retval = scanf("%d", &x))!= EOF && (retval == 1))
if you're allowed to #include , there are two convenient functions bool kbhit() and char getch().
So you can write
char c=0;
if(kbhit()) c = getch();
if(c== whatever code ctrl+d returns) x=EOF;
Hint: Take a look at what scanf(%d,&x) returns when you enter a letter instead of a number.
You can read char by char input :
#include <stdio.h>
int main ()
{
int i;
int x = 0;
int nb = 0;
while(x != EOF)
{
printf("\nHow many circles do you want to write?\n");
nb = 0;
for (x = getchar(); x != '\n'; x = getchar()) {
if (x == EOF)
goto end;
if (x >= '0' && x <= '9') {
nb = nb * 10 + x - '0';
}
}
for (i = 0; i < nb; i++)
{
putchar('o');
}
}
end:
printf("\n\n Bye! \n\n");
return 0;
}

Assigning a user-entered char to a variable

I'm having a few issues successfully storing a user entered char to a variable, the variable which then needs to be used in a different part of the program.
The program in question is supposed to do the following things:
Take a set of user entered values
Place those values into an array of predetermined size
Prompt the user if they would like to see the array
If 'Y', pretty print the array.
I will show you the second part of the program here, in code fragment form, since the first part (placing the values into the array) works fine:
char input, confirm;
printf("Would you like to view the array? Y/N: ");
while ((input = getchar()) != EOF){
confirm = putchar(input);
if (confirm == 'Y'){
printf("[");
for (i = 0; i < maxvals; i++){
if (i != maxvals - 1){
printf("%d,", A[i]);
}
else{
printf("%d", A[i]);
}
}
printf("]");
}
printf("\n");
All variables are obviously pre-declared. Lines 2 and 3 are where I'm having an issue right now.
When I try to run the program, I get:
$ arrays.exe
Enter as many as 10 values, ^D to end
1 2 3
^D
3 values read into array
Would you like to view the array? Y/N: ♦
Y
Y
Note the program just repeats what the user entered. I tried this also (in place of the while loop):
confirm = getchar();
But this just terminates the program. I'm also worried that my if (confirm == "Y") line won't work, but based on my previous programming experience I think it should?
I'm pretty sure I've given all the necessary code but if you want the entire program please tell me so I can edit this.
EDIT:
No one mentioned scanf. It solved the problem. Here is the working code for future reference:
while (scanf("%c", &confirm) == 1){
if (confirm == 'Y'){
printf("[");
for (i = 0; i < n; i++){
if (i != n - 1){
printf("%d,", A[i]);
}
else{
printf("%d", A[i]);
}
}
printf("]");
break;
}
}
return 0;
You say it didn't work, but you don't say what the symptoms of not working were. That might help. In any case, two things I see as probable problems:
putchar(input) is not doing anything useful. putchar does not write values to variables (you are trying to assign to confirm), it writes to the standard output of the program (not at all the same thing). I don't think you want to use putchar at all.
If confirm is a char, you want to compare to 'Y', which is a character, not "Y", which is a string. It might help to see how confirm is declared.
This is a simplified example of what you are trying to do. There is no way to stop this loop as the eof character is '\0' unless you are reading input from a file (aside from cntrl+c or the exit button if you are working on a console application). A character has to be compared to a letter in single quotes. Also, as the previous poster mentioned, putchar is not doing what you anticipate.
Here is the documentation on that function: http://www.cplusplus.com/reference/cstdio/putchar/
int main()
{
char input, confirm;
printf("Would you like to view the array? Y/N: ");
while ((input = getchar()) != EOF){
if (input == 'Y'){
printf("!");
}
}
return 0;
}
here is your code, cleaned up some
and not using a 'input' variable
and not using a call to putchar()
and 'confirm' properly declared as an int
// this assumes that A[] and maxvals and i are already defined and set
int confirm;
printf("Would you like to view the array? Y/N: ");
while ((confirm = getchar() && !( 'Y' == confirm || 'N' == confirm ) && EOF != confirm )
{
if( EOF == confirm ) exit(1);
else printf( "invalid input: please enter: 'Y' or 'N'");
} // end while
// when get here, confirm contains 'Y' or 'N'
if ( 'Y' == confirm )
{
printf("[");
for (i = 0; i < maxvals; i++)
{
if (i != maxvals - 1)
{
printf("%d,", A[i]);
}
else
{
printf("%d", A[i]);
} // end if
} // end for
printf("]");
} // end if
printf("\n");

Resources