I understand there are bugs with "Bad Input" but for some reason i cant even get good input to go through. It's either returning a value of 10 or 0 and i can't seem to find the reason why. Below is where i am calling it:
var1 is datatype float. All headers are included that are needed.
floatHolder is datatype char array.
Below is where i am calling it:
scanf("%s", &floatHolder);
var1 = inputchecker(floatHolder);
this is the function that is called:
float inputchecker(char *charArray)
{
float f = 0;
float f2 = 0;
int i = 0;
int z = 0;
int badInput = 0;
char errorArray[15];
func1:
while (i<strlen(charArray))
{
if (charArray[i]<48 || charArray[i]>57)
{
if (charArray[i] == 46)
{
i++;
goto func1;
}
printf("\n Entered value contains alphabets or symbols, please enter numerical/Floating point values only.\n");
printf("Re-enter Correct Input Please: ");
scanf("%s", &errorArray);
getchar();
badInput = 1;
goto func2;
}
i++;
}
func2:
while (z < strlen(errorArray) && badInput == 1)
{
if (errorArray[i] < 48 || errorArray[i]>57)
{
if (errorArray[i] == 46)
{
z++;
goto func2;
}
printf("Re-enter Correct Input Please: ");
scanf("%s", &errorArray);
getchar();
}
z++;
}
badInput = 0;
f = atof(charArray);
f2 = atof(errorArray);
if (f == 0)
{
return f2;
}
if (f2 == 0)
{
return f;
}
}
For some reason after the function is called it shows a correct return value ex. if i give it 4 it will return 4 but var1 will show a insanely large number, 0, and 10. If anyone can let me know what i'm doing wrong it would be greatly appreciate.
I tried out your routine and received similar results. Then I realized what you problem is. You probably neglected to put a function prototype at the top of your file.
float inputchecker(char *charArray);
By neglecting to use a prototype the compiler will have to guess the signature of the function and the stack may not be restored properly and your return value then will be corrupted.
When I added the prototype at the top of the file, everything worked fine for valid float inputs such as 3.14
Note: different versions of C will behave differently. For example C89/C90 will 'guess' what the parameters will be without a prototype. This can be quite dangerous and it is what I think happened in your situation. I think C99 works in a similar way but with some differences.
Another, proof that you are not using a prototype is that you are receiving integer answers. When the compiler 'guesses' the prototype, it will typically return an int. Furthermore, this also explains why you are getting the same results for different input, you are getting the contents of the same memory location (not your f variables) due to the stack corruption.
Its very very good practice to always define function protoypes at the top of your file.
Related
This question already has answers here:
C warning 'return' with no value, in function returning non-void
(5 answers)
Closed 1 year ago.
#include<stdio.h>
#include<conio.h>
int SumEvennatural(int);
int main()
{
int n;
printf("Enter N:");
scanf("%d", &n);
printf("sum %d", SumEvennatural(n));
getch();
return 0;
}
int SumEvennatural(int n)
{
int s = n * 2;
if (n == 0)
return ; //i am asking here can i write
else
{
if (s % 2 == 0)
return s + SumEvennatural(n - 1);
}
}
i just need to know that is this a correct way to write return only istead of return 0 or 1 or any variable
this way i am getting warning the warning i am getting
In c each function when declared also defines what is the return type of this function. In your case the return type is int because you declare it as int SumEvennatural(int);. A return without a value is only allowed in void functions, i.e. functions that do not return anything.
EDIT: A valid point made by Some programmer dude in the comments is that the return in the main function may be omitted and the compiler will implicitly add a return 0. Still a return in the main without an explicit value will not work.
You can't.
Assume that you could somehow "return" from SumEvennatural(). However, the code must have entered this final call from this line:
return s + SumEvennatural(n - 1);
So what value "X" should be used in s + X ?
Therefore when the function is declared to return int is must return an integer in all possible branches.
The workaround this issue is passing the actual sum as the reference (via a pointer) and update it only when a specific condition is met.
void SumEvennatural(int n, int *sum)
{
int s = n * 2;
if (n == 0)
return ;
else
{
if (s % 2 == 0) {
// update the sum and enter the next recursive call
*sum += s;
SumEvennatural(n - 1, sum);
}
}
}
// usage:
int sum = 0;
SumEvennatural(n, &sum);
printf("sum %d", sum);
You declared a function that is returning an integer.
This means that where you call the function you are expecting to be returned a value.
Now you ask whether you can return without giving a value.
You actually can (https://godbolt.org/z/MbxTPKxe7), that's why that's only a warning. The returned value is not defined to any fixed value. It is compiler and runtime dependent what value is returned in this case.
So you can see that it is not recommended because that's a source of errors.
Your goal should be to write warnings free code.
As said by others, you have to return an integer from your funcion, because of its prototype.
However, you can return e.g. -1, and use this value to check for error in the calling code, for exemple:
if (SumEvennatural(n) < 0) {
printf("An error occured");
exit(1); // Or whatever you wanna do in case of error
}
Another solution is to make your function return an 'exit status' (or nothing if you don't want to manage errors, and store your sum in a pointer, passed as paremeter, as shown in this answer.
The following is the code that I wrote. I feel like I have missed something with the pointer or might have made mistake in the calculation. But as for as I see, everything seems good for me but when I enter, for example: hello or anything else, it gives me 0.00 as output.
The below is correct
Enter a number:
6
Your number is: 6.00
But this why?
Enter a number:
h
Your number is: 0.00
Following is the complete code:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 250
float myAtof(char *string, char *error);
int main() {
char string[SIZE]; // Array declaration.
float fnum1;
char errorState=0;
printf("Enter a number:\n");
gets(string);
fnum1=myAtof(string,&errorState);
if (errorState == 0) {
printf("Your number is: %.2f \n", fnum1);
} else if (errorState == 1) {
printf("Error has been occurred due to inappropriate input!\n");
}
return 0;
}
float myAtof(char* string, char* error) {
*error != '1';
float num= 0;
float decimalFlag = 1;
int decimalNumberFound = 0;
for (int i = 0; string[i]!= '\0'; i++) {
char ch = string[i];
if (ch != '.' && (ch < '0' || ch >'9')) {
error ='1';
return 0;
}
if (decimalNumberFound == 1 && ch == '.') {
error = '1';
return 0;
} else {
num = num* 10 + (ch - '0');
if (decimalNumberFound == 1)
decimalFlag *= 10;
}
}
num = num / decimalFlag;
return num;
}
Since your myAtof routine has a parameter for reporting an error and your main routine tests the error-reporting variable, errorState, presumably you expect the program to print an error message when you enter “h” or other non-numerals, and your question is why it prints “0.00” rather than the error message.
In the function declared with float myAtof(char* string, char* error), error is a pointer, and *error is the thing it points to. So, when the code executes error = '1';, that attempts to set the pointer to '1'. It does not change the thing it points to.
When you compiled this, the compiler issued a warning message, something like “warning: incompatible integer to pointer conversion assigning to 'char *' from 'int'”. You should not have ignored that message.
The function also contains the statement *error != '1';. That statement does nothing. It says to compare the value of *error to '1' to see if they are unequal. The result of the != operator is 1 or 0 indicating whether the values are unequal or not. But the statement does nothing with that result. It is just discarded, so the statement has no effect.
Nothing in your function changes the value of *error, so the thing it points to, errorState in main, is never changed. So main does not see that an error has occurred. It evaluates errorState==0 as true and executes printf("Your number is: %.2f \n", fnum1);.
To fix this, delete the statement *error != '1'; and change the two error = '1'; statements to *error = '1';.
Additionally, change '1' to 1. Setting *error to '1' sets it to the code for the character “1”. It does not set it to the value 1, which is what errorState == 1 tests for. Typically, an error status would be either 0 or 1, not 0 or '1'.
Also change else if (errorState == 1) to else. When you have an if and else that are intended to completely select between some condition X and its alternative, you do not need a second test. With your code if (X) { … } else if (Y) { … }, the first { … } is executed if X is true, the second { … } is executed if X is false and Y is true, and neither is executed if X is false and Y is false. But it should never be the case that X is false and Y is false—you want the program always to either have a number or have an error status. There should be only two possibilities, not three. So use just else, not else if.
(Conceptually, it is a bug for the program to have errorState be something other than 0 or 1, so the program would never have both X false and Y false if it were working, and the else if would be okay. But you did have a bug, and that would cause neither { … } to be executed. Designing the code to use else instead of an unnecessary else if makes it a little more resistant to misbehaving when there is a bug. Designing programs to be robust in this way is useful.)
Also pay attention to warning messages from your compiler. Preferably, tell the compiler to treat all warnings as errors, so that your program will not compile while warning messages remain. If you are using GCC or Clang, use the -Werror switch. If you are using Microsoft Visual C++, use /WX.
I want to make this program say that if you enter 1 the screen will display "yes G is the 1st note in a G chord", if you enter anything else it will print "wrong!" and then loop back into the beginning, here is my attempt at it. Also, I know there are different ways to do this, but it is for a school assignment and the enum data-type is necessary, though this code is far reaching for just displaying use of enum, it bothers me I can't get this to work. Any pointers? (no pun intended).
enum Gchord{G=1,B,D,};
int main(){
printf( "What interval is G in the G chord triad \nEnter 1 2 or 3\n" );
int note;
scanf("%i",¬e);
if (note = 1 ){
printf ("Yes G is %ist note in the G-chord\n",G )};
else(
printf("no, wrong");
return(0):
};
note = 1 is assigning note with the value 1. You are looking to compare note with 1 and therefore you need the operator ==. Read up on comparison operations here:
http://en.cppreference.com/w/cpp/language/operator_comparison
To be crystal clear:
note = 1; // Assigning note to 1, note is now the value 1
note == 1; // Comparing note to 1, true if note is 1, false otherwise.
You also have plenty of other problems:
In printf ("Yes G is %ist note in the G-chord\n",G )}; Lines end with semicolons, if statements don't.
else( else doesnt take an argument and should use a curly brace. else {
return(0) Return is not a function.
Your compiler with warnings on full (-Wall) will tell you all of these things. Things in the list above should have been compiler errors.
There a lot of problems in your code, but the main one is because you try to assign 1 to note instead of the comparission ==.
Another thing is that you never check scanf for errors.
There are parentheses and brackets used wrong.
int main(){} shoudl be at least int main(void){}.
The return statement should be not treated as a function, there are no need of those parentheses around (0) and should end with a semicol ; and not with :.
Now the following should explain you better what you probably tried to do:
#include<stdio.h>
enum Gchord{G=1,B,D,};
int main(void){
printf( "What interval is G in the G chord triad \nEnter 1 2 or 3\n" );
int note;
if(scanf("%i",¬e) == 1){
if (note == 1 ){
printf ("Yes G is %ist note in the G-chord\n",G );
}else{
printf("no, wrong");
}
}else{
printf("Error, scanf\n");
}
return 0;
}
I don't know where to start. Your code has a lot of errors.
Code formatting: it is very important to learn how to format your code so it becomes easier to read it.
int note; variables should almost always be declared at the top and also initialized (in this case with int note = 0;
If you separate something with , enter a space behind it. not scanf("%i",¬e); but scanf("%i", ¬e);
To compare if 2 values are equal, use ==. A single = is used to assign values to a variable. Wrong: if (note = 1 ) Right: if (note == 1)
You are using a wrong bracket for the else that you do not even close.
And for your problem of looping, you should read up about while loops and ask again if you don't understand them.
enum Gchord{G=1,B,D,};
int main() {
int note = 0;
printf("What interval is G in the G chord triad \nEnter 1 2 or 3\n");
scanf("%i", ¬e);
if (note == 1) {
printf ("Yes G is %ist note in the G-chord\n", G);
}
else {
printf("no, wrong");
}
return 0;
};
There are a myriad of syntax errors in here including the one everyone has pointed out that note = 1 assigns a value of 1 to the note variable instead of testing for equality. You want the == operator here.
Also you aren't really using the enum, your teacher probably wont pass you on this.
I modified your code a bit to make a little more use of the enum and to do the loop you are looking for.
enum Gchord { EXIT, G, B, D, };
int main()
{
while (true)
{
printf("What interval is G in the G chord triad \nEnter 1, 2, 3, or 0 to exit\n");
Gchord note;
scanf("%i", ¬e);
if( note == EXIT )
break;
if (note == G)
printf("Yes G is %ist note in the G-chord\n", G);
else
printf("no, wrong\n");
}
return(0);
};
I can't quite figure out what my issue is here. I keep getting an error in my code.
Error: Run-Time Check Failure: Variable used without being initialized.
: warning C4700: uninitialized local variable 'b' used
can someone help me solve this problem ? Any help would be appreciated.I'm using visual studio as a compiler for C and I'm a beginner in it and this is a one of the assignment. I don't see why i keep getting this issue if i input "int b;" in the beginning of the program. Wouldn't that variable be initialized?
Here is the code:
#include <stdio.h>
//Create a program that asks the user to enter a number until the user enters a -1 to stop
int main()
{
int b;
//as long as the number is not -1, print the number on the screen
while(b!=-1) {
printf("Hello there! would you please enter a number?");
scanf(" %d",&b);
//as long as the number is not -1, print the number on the screen
if(b!=-1){
printf("Thank you for your time and consideration but the following %d you entered wasn't quite what we expected. Can you please enter another?\n",b);
//When the user enters a -1 print the message “Have a Nice Day :)” and end the program
}else {
printf("Have a Nice Day :), and see you soon\n");
}
}
return 0;
}
When you declare a variable, such as you have:
int b;
It is not initialised to have any value, it's value is unknown until you initialise it.
To fix this error, replace
int b;
With
int b = 0;
Error is here:
int main()
{
int b;
//as long as the number is not -1, print the number on the screen
while(b!=-1) {
Since you haven't initialized b, it can be anything. You then use it as a condition for while loop. This is very dangerous.
It may be that system randomly assign value of -1 ( its a rare possibility ) to it .. in that case your while loop will not be actioned
Intialize b to some value
For eg do this:
int b = 0;
You're doing:
int b;
and then doing:
while(b!=-1) {
without ever initializing b. The problem is exactly what your warning is telling you it is.
C does not automatically initialize local variables for you, the programmer has to take care of that. int b allocates memory for your variable, but doesn't put a value in there, and it will contain whatever garbage value was in that memory prior to allocation. Your variable won't be initialized until you explicit assign, or another function explicitly assigns, a value to it.
int b;
is a variable declaration. Explicitly, the value is not initialized. The compiler will emit instructions for the program to reserve space to store an integer at a later time.
int b = 1;
this is a variable declaration with initialization.
int b;
while (b != -1)
this is use of an uninitialized variable, but so is
int a = rand() % 3; // so 'a' can be 0, 1 and or 2.
int b;
if (a == 0)
b = 1;
else if (a == 1)
b = 2;
printf("b = %d\n", b);
this is also a potential cause of uninitialized use of b. If 'a' is 2, we never assign a default value to b.
Upshot is you should always try to specify the default value with the declaration. If the logic that will determine initialization is complex, consider using an out-of-bounds value, as you are using -1.
Can you spot the bug in the following?
int b = -1;
if (a == 0)
b = 1;
else if (a == 1)
b = 2;
else if (a > 2)
b = 3;
if (b == -1) {
// this is an error, handle it.
}
My assignment is to fix the code. I have my edited code below and the original code below that. I figure I still have a few errors in here. My error checking doesnt seem to work, and I am not sure if my getchar() function is written or working properly.
Please assume I know nothing becasue that is fairly accurate.
The code compiles, but the answer is always 2. I am about 4 hours into this piece of code with 3 more to work after this.
My code
#include <stdio.h>
double get_number(double num);
main () {
double n1,n2,n3;
double average;
printf("\nCompute the average of 3 integers\n");
printf("--------------------------------\n");
n1 = get_number(1);
n2 = get_number(2);
n3 = get_number(3);
average = (n1 + n2 + n3)/3;
printf("The average is %0.2f\n",average);
}
double get_number(double num) {
double value = 0;
char c;
int i;
printf("Please input number %d: ", num);
while (c = getchar != '\n') {
if ( (c>9) || (c<0) ) {
printf("Incorrect character entered as a number - %c\n",c);
return(0);
}
else {
value = num;
}
}
return(value);
}
Original code
#include <stdio.h>
main () {
double n1,n2,n3;
double average;
printf("\nCompute the average of 3 integers\n");
printf("--------------------------------\n");
n1 = get_number(1);
n2 = get_number(2);
n3 = get_number(3);
average = (n1 + n2 + n3)/3;
printf("The average is %0.2f\n",average);
}
double get_number(int num) {
double value = 0;
char c;
printf("Please input number %d: ", num);
while (c = getchar() != '\n') {
if ( (c<=9) && (c>=0) ) {
printf("Incorrect character entered as a number - %c\n",c);
exit(-1);
}
else {
value = 10*value + c - '0';
}
}
return(value);
}
A few issues:
1. You should be using '9' and '0', since you want the ASCII values for digit '9' (0x39) and '0' (0x30), not 0x9 and 0x0.
if ( (c>'9') || (c<'0') ) {
2. != has higher precedence than =, so you need parens. Learn operator precedence, and if you're in doubt, use parens:
3. getchar is a function not a variable.
while ((c = getchar()) != '\n') {
4. You use the wrong conversion. num is a double, so you would need %f. Or, you could make num a int.
printf("Please input number %f: ", num);
5. You never actually use c in any way (except error checking). You always return 0 or num (see your else clause), which makes no sense. The else body of the original is correct.
You got the floating point parsing all wrong and shouldn't be doing it yourself. There's an easier way:
double get_number(double num) {
double value = 0.0;
printf("Please input number %lf: ", num);
scanf("%lf", &value);
return(value);
}
The issues with the original program are:
getchar() returns an ASCII code, and the condition was wrong. When checking for boundaries, use ((c<'0') || (c>'9')).
For the exit function you need to include "stdlib.h".
For the main function to understand what is get_number, you need to either move the function to be before the main function, or you can use a forward declaration.
The assignment operator (=) has lower precedence than the inequality operator (!=), so you need to use parenthesis, like: ((c = getchar()) != '\n')
You have actually created several more issues, so I wouldn't rely on your code.
In any case, in general - it is advised you study how to use a debugger. Once your code is compiling (and for that you'll need to get accustomed to the compilation error messages), you need to start debugging your code. I suggest you take some time to learn how to set breakpoints, set watches, and go step by step into your code. That skill is absolutely essential for a good developer.
Here's how I'd go about correcting the code ...
http://ideone.com/a0UMm -- compilation errors
http://ideone.com/ljUg1 -- warnings, but it works now
http://ideone.com/Qd0gp -- no errors, no warnings, test run ok
For 1. I used the "original code" as posted by you.
For 2. I used int main(void), declared the function get_number before defining main, added parenthesis in line 20, and added #include <stdlib.h>
For 3. I added return 0; before the final } of main. I also removed the extra output that messed up the ideone interface (it looks better on an interactive interface)
Edit more tests needed to complete the task of correcting the original code