For example, if I want to write a code to average an unspecified number of numbers that the user enters, how can I make it so that the user can determine the number of numbers? ie. if the user wants to average just three numbers, he types them in one at a time, and then types in something to signal that this is it.
I wrote something like
while(i!=EOF){
printf("type in a number: \n");
scanf("%f",&i);
array[x]=i;
x++;
}
"and then some code to average the numbers in the array".
The idea was that if the user wants to signal that he finished entering numbers, he types in EOF and then the while loop will stop, however this isn't working. When I type in EOF at the terminal, it just writes "type in a number:" indefinitely.
scanf returns information in two different ways: in the variable i, and as its return value. The content of the variable i is the number that scanf reads, if it is able to return a number. The return value from scanf indicates whether it was able to read a number.
Your test i != EOF is fundamentally a type error: you're comparing the error indicator value EOF to a variable designed to hold a floating-point number. The compiler doesn't complain because that is accidentally valid C code: EOF is encoded as an integer value, and that value is converted to a floating-point value to perform the comparison. In fact, you'll notice that if you enter -1 at the prompt, the loop will terminate. -1 is the value of the EOF constant (on most implementations).
You should store the return value of scanf, and store it into a separate variable. If the return value is EOF, terminate the loop. If the return value is 1, you have successfully read a floating-point value.
If the return value is 0, the user typed something that couldn't be parsed. You need to handle this case appropriately: if you do nothing, the user's input is not discarded and your program will loop forever. Two choices that make sense are to discard one character, or the whole line (I'll do the latter).
double i;
double array[42];
int x = 0;
int r = 0;
while (r != EOF) {
printf("type in a number: \n");
r = scanf("%f", &i);
if (r == 1) {
/* Read a number successfully */
array[x] = i;
x++;
} else if (r == 0) {
printf("Invalid number, try again.\n");
scanf("%*[^\n]"); /* Discard all characters until the next newline */
}
}
You should also check that x doesn't overflow the bounds of the array. I am leaving this as an exercise.
I want to do it by typing in something that's not a number
Then get the input as a string, and exit if it cannot be converted to a number.
char buf[0x80];
do {
fgets(buf, sizeof(buf), stdin);
if (isdigit(buf[0])) {
array[x++] = strtod(buf);
}
} while(isdigit(buf[0]);
In case of no input scanf() does not set i to EOF but rather can return EOF. So you should analyze scanf() return code. By the way you can receive 0 as result which actually means there is no EOF but number cannot be read.
Here is example for you:
#include <stdio.h>
#define MAX_SIZE 5
int main()
{
int array[MAX_SIZE];
int x = 0;
int r = 0;
while (x < MAX_SIZE)
{
int i = 0;
printf("type in a number: \n");
r = scanf("%d",&i);
if (r == 0)
{
printf("ERROR!\n");
break;
}
if (r == EOF)
{
printf("EOF!\n");
break;
}
array[x]=i;
x++;
}
}
You cannot write 'EOF'.. since you are reading into a number...
EOF equals -1.. so if he enterd that, the loop would stop
You can test for the return value of the scanf function. It returns EOF on matching failure or encountering an EOF character.
printf("type in a number:" \n);
while(scanf("%f",&i)!=EOF){
array[x]=i;
x++;
printf("type in a number:" \n);
}
Related
The purpose of this code is to sum up to a number greater than zero and then ask the user if they want to sum another number. The summing part of the program works, but I can't seem to get the user input to work correctly. Any help or insight would be appreciated.
#include <stdio.h>
int main(void)
{
char * another;
int start = 0;
int x = 0;
int Input=0;
int sum = 0;
do
{
printf("Please enter a number greater than zero to sum up to: \n");
scanf("%d", &x);
if(start<x)
Input=1;
else
printf("The number needs to be greater than zero.\n");
}
while (Input ==0) ;
while (start <= x) {
sum += start;
start++;
if (start >x)
{
printf("The sum of the numbers 0 to %d is: %d \n" ,x , sum);
}
while (start >x)
{
printf("Would you like to sum another number? Y/N:");
scanf("%s",another);
}
} while ((another =="y")||(another=="Y"));
return 0;
}
There are quite a few things to address here.
char *another allocates no memory for a string to be placed. It is just an uninitialized pointer to memory, containing a garbage value. Utilizing this value in any way will invoke Undefined Behavior.
You must allocate some memory if you want to store a string. The easiest way is on the stack, as a character array:
char another[64];
Strings should not be compared with ==, as that compares their addresses, which even for two identical literals ("a" == "a") might not be the same. Use strcmp to compare strings.
There is no while ... while.
while (start <= x) {
/* ... */
} while ((another =="y")||(another=="Y"));
This is one while statement with a Compound Statement for a body, followed by another, separate while statement with an empty Expression Statement for a body.
More clearly read as:
while (start <= x) {
/* ... */
}
while ((another =="y")||(another=="Y"));
It is of course possible to have a do ... while whose body is itself a while statement
do
while (/* ... */) {
/* ... */
}
while (/* ... */);
but this is a bit confusing, and probably not what you really want.
The return value of scanf should be checked such that it matches the number of conversions you expected to succeed, in order to proceed to work with that data.
if (scanf("%d", &x) != 1) {
/* Something has gone wrong, handle it */
}
Failure to check this value can result in using uninitialized or otherwise indeterminate data.
This is also where one of the major pitfalls of scanf occurs:
In the event that scanf cannot apply a conversion to the input stream, the data is left in the input stream, and scanf fails early. Your next call to scanf will read that same data unless it is purged first (usually accomplished by consuming characters until a newline or end-of-file is reached).
This is why it is generally advised to separate your reading and your parsing to gain more control. This can be achieved with fgets and sscanf, to first read a line of input, and then parse it.
The other option is to simply terminate the program on any failure, which is what I've done in the example below (for simplicity's sake).
Additionally note that scanf("%s", buffer) is vulnerable to overflowing buffer. Always limit your input using field width specifiers, in the form scanf("%127s", buffer), which should be the length of your buffer minus one (leaving room for the NUL terminating byte).
Some things to consider:
Allocate memory for your string buffer.
Limit the amount of information that can be read into your buffer.
Handle errors in some way.
Use continue or break to help structure your flow.
Use separate functions to clarify a common task.
An example:
#include <stdio.h>
int seqsum(int from, int to) {
int sum = 0;
while (from <= to)
sum += from++;
return sum;
}
int main(void) {
char another[64];
int working = 1;
int n;
while (working) {
printf("Please enter a number greater than zero to sum up to: \n");
if (scanf("%d", &n) != 1) {
fprintf(stderr, "Invalid input or read error.\n");
return 1;
}
if (n < 0) {
printf("The number needs to be greater than zero. Retrying..\n");
continue;
}
printf("The sum of the numbers 0 to %d is: %d\n", n, seqsum(0, n));
printf("Would you like to sum another number? (y/n): ");
if (scanf("%63s", another) != 1) {
fprintf(stderr, "Invalid input or read error.\n");
return 1;
}
working = (another[0] == 'y' || another[0] == 'Y');
}
}
As an addendum, perhaps you were trying to read a single character?
Character constants are denoted by their enclosing single quotes (e.g., 'A'), and can be compared with the == operator.
The scanf format specifier for a single character is "%c". To skip leading white space (e.g., a line feed), you can add a space before the format specifier: " %c". The address of your char is given to scanf with the address-of operator (&).
char ch;
if (scanf(" %c", &ch) != 1)
/* failure */;
else if (ch == 'a' || ch == 'b')
/* do something */;
why the while loop starts executing infinite if I enter any alphabet and when I enter any number it executes only once.
Scanf("%d",&a) function returns 1 for any number and 0 for any character or string. As I know EOF is not equal to 1 and 0.
#include<stdio.h>
int main
{
int a;
while(scanf("%d",&a) != EOF)
{
printf("hi devender \n");
}
return 0;
}
// input buffer==> 42foo\n
scanf("%d", &a); // returns 1 (not EOF), a is now 42
// input buffer==> foo\n
scanf("%d", &a); // returns 0 (not EOF), see comments about a
// input buffer==> foo\n // no change
scanf("%d", &a); // returns 0 (not EOF)
// input buffer==> foo\n // no change
scanf("%d", &a); // returns 0 (not EOF)
// input buffer==> foo\n // no change
... ... infinite loop
In short, don't compare the return value from scanf() with EOF; compare with the number of expected assignments.
if (scanf("%d%s%d%d", &a, name, &b, &c) != 4) /* error */;
Per the scanf() man page (bolding mine):
RETURN VALUE
On success, these functions return the number of input items
successfully matched and assigned; this can be fewer than provided
for, or even zero, in the event of an early matching failure.
If you don't enter a number, you get a matching failure and scanf() returns zero.
I don't know what you are trying to do, but to understand that the problem with the infinite loop is that the buffer is not empty, try this code.
include
int main(void)
{
int a,c;
while(scanf("%d",&a) !=EOF)
{
printf("hi devender \n");
while ( ( c = getchar() ) != EOF && c != '\n' ) ; //empty the buffer
}
printf("Finished");
return 0;
}
why the while loop starts executing infinite if I enter any alphabet
scanf("%d",&a) function returns 1 for any number and 0 for any character or string. As I know EOF is not equal to 1 and 0
It appears the key issues for OP is that on a matching failure, the text in stdin is not consumed. So once an "abc\n" is entered. the 'a' and the rest, remain in stdin until some other input function reads it. As code lacks other ways to read data, we have an infinite loop.
A common work-around it to read the offending character
#include<stdio.h>
int main() {
int scan_count;
int a;
while((scan_count = scanf("%d",&a)) != EOF) {
if (scan_count == 0) {
getchar();
}
printf("hi devender \n");
}
return 0;
}
Or as others suggest, consume to the end of the line of input.
I'm working on my first simple C program in Visual Studios 2017. The goal is to get two user inputs which have to be integers.
I go through the array and check if every character is an integer but it still returns "The input is not a valid number". Also after retrying 3 times the console crashes.
"projectExample.exe has triggered a breakpoint. occurred" is the displayed message.
int main()
{
char userInputM[10];
char userInputN[10];
//get the value of M from the user
printf("Enter a value for M: ");
fgets(userInputM, sizeof(userInputM), stdin);
//printf(userInputM);
//check that the entered value for M is a valid positive number
const int lenOfInput1 = strlen(userInputM);
for (int i = 0; lenOfInput1; i++) {
if (!isdigit(userInputM[i])) {
printf("The input is not a valid number. Try again");
printf("Enter a value for M: ");
fgets(userInputM, sizeof(userInputM), stdin);
printf(userInputM);
}
}
//check that the entered value for N is a number
//convert the user input for M to an int for calculation
//int factorM = atoi(userInputM);
//printf("%d", factorM);
//int result = calculate();
//int a;
//scanf("%d", &a);
}
If you need to make sure that the number is an integer, you could read in the input into an int with scanf() and check the return value.
int M, rv=-1;
while(rv!=1)
{
if(rv==0)
{
getchar();
}
rv=scanf("%d", &M);
}
scanf() would return the number of variables to which values were assigned successfully which will be 1 if the above scanf() is successful.
If the input was not a number and hence the scanf() returns 0, the entered value, which is not a number, is still left unconsumed in the input buffer and that needs to be consumed. It could be done with a getchar().
Otherwise, scanf() will keep trying to read the same value and rv will be 0 each time.
In this way, you don't need a string buffer or a need to use atoi().
Have a look here as well.
As pointed out in the comments, fgets() will read in the trailing new line (\n) into the string and \n is not a digit.
You could replace the \n with \0 like
str[strlen(str)-1]='\0';
int count = 0;
int i = 0;
while (userInputM[i])
{
if (userInputM[i] >= '0' && userInputM[i] <= '9') //if it's an integer
{
++count; //do something like creating new array and put the
//data inside or in my case I count the # of ints
++i;
}
else
++i;
}
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");
}
}
}
What is wrong with this ? Also, I have to use scanf(). It is supposed to read any integers and sum them, the loop is to stop when 0 is entered..
main (void){
int a;
int r=0;
while(scanf(" %d",&a)){
r=r+a;
}
printf("the sum is %d\n",r);
return 0;
}
Quoting from man
These functions return the number of input items assigned. This
can be
fewer than provided for, or even zero, in the event of a matching fail-
ure. Zero indicates that, although there was input available, no conver-
sions were assigned; typically this is due to an invalid input character,
such as an alphabetic character for a `%d' conversion.
The value EOF is
returned if an input failure occurs before any conversion such as an end-
of-file occurs. If an error or end-of-file occurs after conversion has
begun, the number of conversions which were successfully completed is
returned.
So, that pretty much explains what is returned by scanf().
You can solve the problem by adding ( 1 == scanf("%d", &a) && a != 0 ) as the condition in your while loop like
int main (void)
{
int a;
int r=0;
while( 1 == scanf("%d", &a) && a != 0 )
{
r=r+a;
}
printf("the sum is %d\n",r);
return 0;
}
Also note that you have to specify the type of main as int main().
I would also like to add that the loop will end when you enter a character like 'c' ( or a string ) and it will show the sum of all the numbers you entered before entering the character.
scanf() doesn't return what it has written to the variable. It returns the total number of items successfully filled.
EDIT:
You would be much better off using fgets() to read from stdin and then using sscanf() to get the integer, which you can check against 0.
#define BUFF_SIZE 1024
int main (void)
{
int a;
int r = 0;
char buffer[BUFF_SIZE] = {0};
while(1) {
fgets(buffer, sizeof buffer, stdin);
sscanf(buffer, "%d", &a);
if(!a)
break;
r = r + a;
}
printf("the sum is %d\n", r);
return 0;
}