C Program causing black screen on the console - c

So I was coding this program and after I was done, I tried to run it but for some reason nothing shows up on the console. I went through the code multiple times and tried multiple ways of performing the same function, which is basically to keep on getting inputs from the user until he/she enters 0, then display the largest and second largest number, and if the user enters 0 and there are no numbers available then continue checking. I think may be there is an infinite loop or some other problem with it. Here is the code:
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
void main()
{
int input,z;
int large,small,counter=0;
bool a=false;
while (1){
if(scanf("%d\n",&input)>0)
{
small=input;
counter++;
if(small>large)
{
z=small;
small=large;
large=z;
}
}
else if(scanf("%d\n",&input)<0)
{
printf("Please enter a positive value\n");
}
else if(scanf("%d\n",&input)==0)
{
if(small>0 && large>0)
{
printf("There are in total %d positive integers entered",counter);
printf("The largest number is %d, while the second largest is %d", large,small);
a=true;
break;
}
else
{
printf("You have to enter atleast two positive integers");
}
}
}
}
Any sort of help would be appreciated, thank you.

The scanf function doesn't return the input, it returns how many numbers it read.
Since your code reads numbers one at a time, scanf will always return 1, causing an infinite loop.
To fix this, hoist the scanf call outside the branching code:
while (1) {
scanf("%d", &input);
if (input > 0) ...
else if (input < 0) ...
else ...
}
There are more bugs in your code (Rohan pointed out one of them) but this should solve the black screen.

Each time you check the value entered, you're doing another scanf() or trying to read a new value instead of checking the value of the number that was entered. And the value you're checking is the return value of scanf(), but the number that's entered is actually stored in your "input" variable. So yes, there are a few things going on here, but you're essentially in an infinite loop because the entered values aren't getting read or evaluated properly.
The C function scanf() doesn't take a newline. Instead use:
scanf("%d", &input);
Also, initialize your "large" variable to 0 when you define it (it's value is not 0 and will give you unpredictable results):
int large = 0, small, counter = 0;
What you want to do is ONLY one scanf() at the top of your while loop to read in a number. After that, your if's should be testing the value of "input":
while (1)
{
scanf("%d", &input);
if (input > 0) /* positive number entered */
{
/* do something */
} else if (input < 0) /* negative number entered */
{
/* print error */
} else /* no need to test value since it must be 0 at this point */
/* do stuff */
}
}
Happy C coding! ;-)

If you walk carefully through the logic of your program, you'll see it doesn't make sense. For example, if a number is entered, you never print anything.

Related

Issues with using scanf inside a while loop

I’m brand new to programming. I ‘m working on a homework assignment in order to help us understand scanf and arrays. The program is supposed to ask the user to input an unknown set of numbers. Each set of numbers should be separated by a space like below without hitting enter.
14 15 16
The user can also input numbers on a separate line instead using spaces, but again on the last number inputed the user isn’t supposed to hit enter.
12 13
44 55
5
The user should hit ctrl-d to indicate end of input. The program should display the number of elements entered by the user, along with displaying the numbers the user entered. I have been reading around and think I have a basic concept of how scanf works, but I am still having some difficulty. The code kind of works. However, if the user just enters the numbers on one line they need to hit ctrl-d three times in order for it to exit the loop and display the information.
From what I have found online and understand, I think it’s not working because the user hasn’t hit return, so the input hasn’t been flushed into the stdin. So if I'm understanding correctly, the first time I hit ctrl-d it while flush the input. Then the second time I hit ctrl-d it will finally put the EOF into the stream and the third time it will finally read the -1 produced by the EOF and exit the loop.
Is there anyway to force the input stream once ctrl-d is entered.
#include <stdio.h>
int main()
{
int numbers[20];
int i = 0, count, result, n;
int flag = 0;
printf("Please enter a seiries of numbers:\n");
while (flag == 0)
{
result = scanf("%d", &n); //scan user input into n variable along with getting scanf return value and storing in result variable
printf("result =%i \n", result); //Just printing scanf return value to insure it doing what I think it should be doing
if (result == 1)
{
numbers[i] = n; //if scanf return value is 1 places value of n into first element of array
i++; //used to increment my array
flag = 0;//keeps value of flag equal to 0 in order to stay in loop
}
if(result == -1) //checks to see if result = to -1 should be value returned if cntl +d is entered
{
flag = 1; //sets flag to 1 when cntrl +d is entered in order to exit loop.
}
}
for (count = 0 ; count < i ; count++) //loop to print I which is representing number of user inputs and the actual numbers entered by the user.
{
printf("\ni= %i numbers= %i\n", i, numbers[count]);
}
return 0;
}
I won't give you a solution directly, but will try to help you improve coding in C. The more you work with C the more you will find out that one can write pretty compact code, once the language is mastered.
You can omit flag because it depends on result.
And you could omit result because it is just the return value of scanf.
You can omit n and use numbers array directly.
And you could make use of the preprocessor to use a constant number (often for array sizes as in your case).
Have a look at this. Maybe it helps you get an idea:
#include <stdio.h>
#define COUNT 20
main() {
int numbers[COUNT];
int i;
i = 0;
while (scanf("%d", &numbers[i]) == 1 && i < COUNT)
printf("\t%d\n", numbers[i++]);
return 0;
}
P.S.:
I recommend getting acquainted with the different ways of accessing an array and reading about pointers. The have a very close relationship really.
Address of first element in array : numbers
Access ith element of array : numbers[i]
Equivalently : *(numbers + i)
Another equivalence : *(i+numbers)
Surprise, but equivalent again : i[numbers]
Address of ith element of array : &numbers[i]
K&R is a great resource of information and learning.

Why is my while loop acting this way?

I am currently trying to get a while loop working, but it's not going the way I want it too. What I want to do is loop until a specific input is put in. Something must be wrong with my syntax, but I can't figure out what.
#include <stdio.h>
int main()
{
float input = 0;
scanf("%f", &input);
while(input!=0)
{
printf("hello\n");
scanf("%f", &input);
}
return 0;
}
For some reason, it doesn't break out of the while loop when it is zero. I want the while loop to stop working after someone enters 0, but when someone enters 0 it will create an infinite printing of "hello" instead..As you may have guessed, input becomes 0 whenever the user inputs anything besides a float, so if I enter a letter, I am expecting the while loop to stop, but it doesn't ;\
Edit:
Thank you guys for help! I learned and figured out why my logic was wrong (due to lack of understanding how to test the value of scanf)!! Cheers.
input does not become zero if the user enters a non-float. scanf won't change the value, and it won't consume any characters. So, if the user enters a non-float, scanf will keep reading the same characters over and over again.
You can test the scanf return value to see if it successfully read anything. scanf returns the number of fields that were successfully read, so a return value of 0 means that it failed to parse anything:
while(scanf("%f", &input) == 1) {
printf("You entered %f\n", input);
}
Write the loop like
while(input!=0)
{
printf("hello\n");
input = 0.0;
scanf("%f", &input);
}

Trouble figuring out logic for while/if loop in C

I have a some code, and the function I am having trouble with is this:
unsigned int getInputData() {
printf("Please input a positive integer number terminated with a carriage return.\n");
do{
scanf("%c", &input);
if(isdigit(input)) {
temp = charToInt(input);
rValue = mergeInt(rValue, temp);
}
if(rValue >= imax) {
rValue = 0;
printf("ERROR: That is too large of an integer. Please try again. \n");
}
else if(isalpha(input)){
rValue = 0;
printf("This is not a integer. Please try again. \n");
}
else{
printf("OK. This is a good number. \n");
}
} while(1);
}
I'm scanning in each char individually, merging it into an int. Which is exactly what I want to do BUT I only want it to print "OK. This is a good number." once when the user types it in. Example: If someone was to type in: 12345 I want it to return: "OK. This is a good number." once for those 5 char rather than once each. Hoping this makes sense, been at it for awhile so anything will help.
There's huge logic problems behind your code:
You loop infinitely without checking for end of input:
You say you want to tell whether this is a good number when the user inputs several digits, but you do only read one character at a time, and you do not define how a number ends.
Though you do specify to end with a carriage return, you did not design your algorithm that way, you never check for the \n character.
You define a return value for the getInputData() function but you do never return from that function.
You test whether input is a digit to update the value, but for errors you do show an error only if it's an alphabetic character.
Basically, to keep with the way you wrote your algorithm, here's another take:
unsigned int getInputData() {
char input;
long value=0;
do {
scanf("%c", &input);
if (isdigit(input))
value = value*10+input+'0';
else if (input == '\n')
return 1;
else
return 0;
} while(1);
}
int main() {
printf("Please input a positive integer number terminated with a carriage return.\n");
if (getInputData() == 1)
printf("OK. This is a good number.\n");
else
printf("This is not a integer. Please try again. \n");
return 0;
}
but I do exit from the infinite loop to be able to check the result.
N.B.: for the purpose of the example, I did not check for overflows.
N.B.1: I kept using scanf() to stay close to your code, but if you only want to read one character at a time, it is better to use getchar() which is way simpler and faster.
N.B.2: you can also simplify your code by using more features of scanf():
unsigned int getInputData() {
unsigned input;
long value=0;
int n;
do {
n = scanf("%u", &input);
if (n == 0)
return 0;
else
return 1;
} while(1);
}
You may even try to use scanf("%a[0-9]") which is a GNU extension. See man scanf for more details.

Random guessing game (integer) - bug when entering string

I am making a typical guessing game to learn C for the first time in my life and I noticed a bug. If you enter an integer you will get Guess a higher value or Guess a lower value and that works just fine. But if you put in a string, it goes insane and prints out a lot of strings saying Guess a higher value.
What I am trying to do now is to make a check for if the user enters a string, it will say to the user something like Enter a number, not text. How do I do this?
Is there anything you see that I can improve in this code?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main () {
int secret, answer;
srand((unsigned)time(NULL));
secret = rand() % 10 + 1;
do {
printf ("Guess a number between 1 and 10");
scanf ("%d",&answer);
if (secret<answer) puts ("Guess a higher value");
else if (secret>answer) puts ("Guess a lower value");
} while (secret!=answer);
puts ("Congratz!");
return 0;
}
You are ignoring the return value of scanf, which will tell you if the conversion went well or not. scanf will return the number of items assigned, so if it returns 1 you know that answer was assigned to a number. If it returns 0, you know that something went wrong.
What I am trying to do now is to make a check for if the user enters a
string, it will say to the user something like Enter a number, not
text. How do I do this?
scanf does formatted input. You may also want to check out advanced formatting specifiers in scanf -- such as ignoring parts of the input, specifying buffer size for reading in strings, specifying only a particular set of characters that you want to read etc. If you want to verify input, you are probably best of reading a line from the console using fgets and then parsing the line.
Is there anything you see that I can improve in this code?
You may want to improve your random number generation algorithm. Read the C FAQ.
Check the return value of scanf . It will return the number of items successfully matched and assigned. In this case if you enter a string then it will not be matched and assigned, but the string stays in the input buffer, and the scanf tries to read it in each iteration and fails, and thus the problem arises.
You may change the code to:
int main () {
int secret, answer;
srand((unsigned)time(NULL));
secret = rand() % 10 + 1;
do {
printf ("Guess a number between 1 and 10");
if (scanf ("%d",&answer) != 1)
{
printf ("\nPlease enter an integer\n\n");
scanf ("%*s");
continue;
}
if (secret<answer) puts ("Guess a higher value");
else if (secret>answer) puts ("Guess a lower value");
} while (secret!=answer);
puts ("Congratz!");
return 0;
}
Note that inside the if the line scanf ("%*s"); is done. In the %*s the * is the input supression indicator, this tells that a string (stands for %s) will be read but the * tells that although the string will be read from the input, it will be discarded. This is being done to simply discard the previously entered string which is not read by the scanf ("%d",&answer) . In case you do not discard the string in the buffer, it will remain, and each iteration the scanf ("%d",&answer) will fail to match any integer, as it will encounter the leftover string in the input buffer.
On the other hand you may read a string and convert the string to an integer.
Like as below:
int main () {
int secret, answer;
char buff[128];
srand((unsigned)time(NULL));
secret = rand() % 10 + 1;
do {
printf ("Guess a number between 1 and 10");
scanf ("%s",buff);
if ((answer = atoi (buff)) == 0)
{
printf ("\nPlease enter an integer\n\n");
continue;
}
if (secret<answer) puts ("Guess a higher value");
else if (secret>answer) puts ("Guess a lower value");
} while (secret!=answer);
puts ("Congratz!");
return 0;
}
atoi () will convert a string to an integer (in 10 base). If the characters which comprises the integer does not contain valid digits, it will return 0. Checking for it we can detect if the user entered correctly. Also because your application needs to enter an integer within 1 and 10 therefore 0 is not included, therefore it is okay to take 0 as an invalid. To get better control on detecting an invalid integer format, and the location of the error in the string use strtol ()
You may want to make a function to check if the input is numeric. Like:
int isNumeric( char *str){
while(*str)
{
if (!isdigit(*str))
return 0;
str++;
}
return 1;
}
int main(){
char guess[3];
int iGuess;
do {
printf("Guess a number between 1 and 10");
gets(guess);
if (!isNumeric(guess)){
printf("Invalid input");
continue;
}
iGuess = atoi(guess);
if (iGuess<secret)
printf("Higher");
else if (iGuess>secret)
printf("Lower");
} while (secret!=iGuess);
printf("Congrats");
return 0;
}
You need to include ctype.h and string.h

Loop that can take user input every time through

How can I make a loop that can take user input every time it loops?
#include <stdio.h>
#define WORD "jumble"
#define JUMBLED "mleujb"
int main()
{
char string[6];
int i = 0;
printf("The jumbled word is ");
printf(JUMBLED);
printf("\nCan you guess the original: ");
while(i == 0)
{
scanf("%d", string);
if (string == "exit")
{
return;
}
if(string == WORD)
{
i++;
printf("Kudos! You've guessed the word!");
}
else
{
printf("English please, good sir. Guess again.\n");
}
}
}
What I had hoped for was that every time the program went through the loop, it would want a new input with the scanf function. However, that apparently does not work that way. Instead, the program takes the value of the first scanf and uses it over and over again. If it is the wrong word, it will have an infinite loop.
This program has more than a few bugs in it: for instance, it does not actually compare the input to the actual word yet. As that does not pertain to the question, it is not my immediate concern.
you are using scanf() wrongly instead of scanf("%d",string) use scanf("%s",string) as %d is used for decimal input and %s is used for string input
Pseudo code for helping you precisely is not great
Also can you define a bit better your question ? you don't really say what is going wrong
but here is my guess
your test is i ==0 which means as soon as your user inputs the right word your exiting your loop...
I would guess your looking for something like
exit_condition = 0;
while (exit_condition == 0)
{
read keyboard entry
if(condition to exit loop)
{
exit_condition = 1;
printf("correct")
}
else
{
printf("try again")
}
}
Concerning the tests I think you need to read up bit on input and tests
try this
http://www.arachnoid.com/cpptutor/student1.html
scanf is incorrect for getting input string. It should be scanf("%s", string) as pointed out by others
String comparison cannot be done by using == in 'C'. It will only compare the address of two strings which will fail. Use 'strncmp' function instead.

Resources