Consider the following code:
#include <stdio.h>
#include <math.h>
#define INFTY 1000.0
#define EPS 0.0001
#define XRANGE 2
#define URANGE 2
float absf(float);
float E(float,float,float,float,float,float);
int main(){
FILE* out;
float T,R,G,ALPHA,STEP,x,u;
char filename [45];
int c;
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("Enter the dimensionless parameters greater or equal to 0:\nT = ");
scanf("%f",&T);
do { c=getchar(); } while ( c != '\n');//flush stdin
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("R = ");
scanf("%f",&R);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("G = ");
scanf("%f",&G);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("alpha = ");
scanf("%f",&ALPHA);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("step size (recommended:0.001 to 0.01): ");
scanf("&f",&STEP);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
if((T<0)||(R<0)||(G<0)||(ALPHA<0)||(STEP<0)) return 1;//crash if <0
sprintf(filename,"%.4g_%.4g_%.4g_%.4g_%.5g.dat",T,R,G,ALPHA,STEP);
out = fopen(filename,"w");
fprintf(out,"#T=%.3e R=%.3e G=%.3e alpha=%.3e\n",T,R,G,ALPHA);
//do the job
fclose(out);
return 0;
}
The issue here is that it seems to completely ignore the last scanf() where the step size is supposed to be entered; it just takes whatever junk was in the memory and goes with it, usually a very small number. This output is very characteristic:
0.000000 0.000000 0.000000 0.000000 72406190763540480.000000
Enter the dimensionless parameters greater or equal to 0:
T = 1
1.000000 0.000000 0.000000 0.000000 72406190763540480.000000
R = 1
1.000000 1.000000 0.000000 0.000000 72406190763540480.000000
G = 1
1.000000 1.000000 1.000000 0.000000 72406190763540480.000000
alpha = 1.2
1.000000 1.000000 1.000000 1.200000 72406190763540480.000000
step size (recommended:0.001 to 0.01): 0.01
1.000000 1.000000 1.000000 1.200000 72406190763540480.000000
As is evident, it's possible to overwrite every variable except the last one. The file is created even before the last scanf() is complete. Moving the step size input to the top produces another issue:
step size (recommended:0.001 to 0.01): 0.01
Enter the dimensionless parameters greater or equal to 0:
T = R = 1
G = 1
alpha = 1.2
^C
In this case, STEP wasn't actually overwritten by 0.01, but remained a very small number.
I have looked for similar cases, but there doesn't seem to be any widespread issues like rogue spaces in the input. I'm flushing stdin after scanf() as suggested here.
I'm looking forward to any advice. Thanks in advance.
You have used '&' in place of '%' in scanf("&f",&STEP);
#include <stdio.h>
#include <math.h>
#define INFTY 1000.0
#define EPS 0.0001
#define XRANGE 2
#define URANGE 2
float absf(float);
float E(float,float,float,float,float,float);
int main(){
FILE* out;
float T,R,G,ALPHA,STEP,x,u;
char filename [45];
int c;
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("Enter the dimensionless parameters greater or equal to 0:\nT = ");
scanf("%f",&T);
do { c=getchar(); } while ( c != '\n');//flush stdin
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("R = ");
scanf("%f",&R);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("G = ");
scanf("%f",&G);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("alpha = ");
scanf("%f",&ALPHA);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
printf("step size (recommended:0.001 to 0.01): ");
Replace &f with %f, it will work in
scanf("&f",&STEP);
do { c=getchar(); } while ( c != '\n');
printf("%f %f %f %f %f\n",T,R,G,ALPHA,STEP);//debug
if((T<0)||(R<0)||(G<0)||(ALPHA<0)||(STEP<0)) return 1;//crash if <0
sprintf(filename,"%.4g_%.4g_%.4g_%.4g_%.5g.dat",T,R,G,ALPHA,STEP);
out = fopen(filename,"w");
fprintf(out,"#T=%.3e R=%.3e G=%.3e alpha=%.3e\n",T,R,G,ALPHA);
//do the job
fclose(out);
return 0;
}
Related
I am trying to write a code in C (gcc) to accept only floating numbers and reject integers, special characters, alphanumeric entries.
I want it to see if printf("First number: \n"); & printf("Second number: \n"); are floating numbers with decimals otherwise ask the user to re-enter a floating number since his first input was invalid.
I want that to happen before it starts calculating.
I need a code expample if possible
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
float a, b, sm;
int i = 2;
printf("First number: \n");
scanf("%f", &a);
printf("Second number: \n");
scanf("%f", &b);
printf ("%.2f + %.2f = %.2f -> Summe \n", a, b, sm = a+b);
printf ("%.2f / %d = %.2f -> Mittelwert \n", sm, i, sm/i);
printf ("%.2f - %.2f = %.2f -> Differenz \n", a, b, a-b);
printf ("%.2f * %.2f = %.2f -> Produkt \n", a, b, a*b);
printf ("%.2f / %.2f = %.2f -> Division\n", a, b, a/b);
}
Thank you for your time!
You could use the return value of scanf() to detect wrong input. (see fscanf() documentation).
Then you'd need to explicitly ignore wrong input (e.g. by scanning "non-newline" while ignoring it), in order to be able to take corrected input from user afterwards. This is not easy, see the article linked at the end.
Do so in a loop until satisfied.
Alternatively (the method widely recommended here on StackOverflow) read whole lines via fgets() into a buffer, then decide on correctness by parsing.
Skip incorrect syntax, simply by reading the next line into the buffer.
If correct, scan from buffer.
Helpful article on the topic: beginners guide away from scanf().
The integers will be converted into floating point numbers, i.e. if the number is given 5 then it'll be converted into 5.0 for the floating point variable implicitly. Hence, none should worry about that.
Use the following program:
#include <stdio.h>
float ask_loop(float f) {
int ret = scanf("%f", &f);
float fl = f;
if (ret != 1) { // if scanf() returns error code
printf("Error! Please input numbers correctly.\n");
fflush(stdin);
fl = ask_loop(f);
}
return fl;
}
int main(void)
{
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
float a, b, sm;
int i = 2;
printf("First number: \n");
a = ask_loop(a);
fflush(stdin);
printf("Second number: \n");
b = ask_loop(b);
printf ("%.2f + %.2f = %.2f -> Summe \n", a, b, sm = a+b);
printf("%.2f / %d = %.2f -> Mittelwert \n", sm, i, sm / i);
printf("%.2f - %.2f = %.2f -> Differenz \n", a, b, a - b);
printf("%.2f * %.2f = %.2f -> Produkt \n", a, b, a * b);
printf("%.2f / %.2f = %.2f -> Division\n", a, b, a / b);
}
Here we've used a function ask_loop() which verifies if the scanf() doesn't returns an exit code. If it doesn't, it means it has accepted the value successfully, otherwise does recursion again. At the end of the function, it returns the number inputted and assigns to the variable in main().
Sample Output:
First number: // --- INPUT
abc
Error! Please input numbers correctly. // --- OUTPUT
2.0
Second number: // --- INPUT
5
2.00 + 5.00 = 7.00 -> Summe // --- OUTPUT
7.00 / 2 = 3.50 -> Mittelwert
2.00 - 5.00 = -3.00 -> Differenz
2.00 * 5.00 = 10.00 -> Produkt
2.00 / 5.00 = 0.40 -> Division (5 -> 5.00)
i have to write a code for university in which i have to read a .txt file that contains three columns: Hour of the day, Solar radiation, Rain meter (mm), and apply a equation to each line consecutively based on information given by the user. i managed to build the code that applies the equation for a single line chosen by the user at a time. How can i apply that equation to every line and display them simultaneously ?
The .txt file i'm using is:
0 -0.82 17.2
1 2386 14.4
2 1980 0.22
3 470 0.0
4 2731 0.2
5 1531 0.0
6 3084 0.4
7 2197 0.4
8 313 0.0
9 1428 0.0
10 47.01 0.0
11 138.8 0.0
12 328.4 0.0
13 431.2 0.4
14 419.6 0.2
15 447.8 0.8
16 572.2 0.2
17 801.5 0.0
18 849.1 0.0
19 561.1 0.0
20 376.6 0.0
21 122.9 0.0
22 -1.69 0.0
23 -1.46 0.0
my code is as follow (please forgive the unpolishness, i'm a begginer in programming):
#include <stdio.h>
#define efi 0.83 //83% , standart solar cell eficiency
int h,a;
int potency (int x, int y, int z)
{
return (x*y*z);
}
int hour[24], i=0;
float radiation[24], rain[24], energ,energk,pt,p,e,ep,ee;
int main()
{
FILE *arq;
arq = fopen("file2.txt", "r");
if(arq == NULL) {
printf("Error! unable to open file! \n");
getchar();
}
else {
printf("File open... \n");
printf("Reading file...\n");
while (!feof(arq)){
fscanf(arq,"%d %f %f\n", &hour[i], &radiation[i], &rain[i]);
i++;
}
printf("Type desired hour \n");
scanf("%d", &h);
printf("type board area m^2\n");
scanf("%d", &a);
printf("type maximum board pontency in WATTS/M^2\n");
scanf("%f", &p);
ep=p*efi; //Board potential after calculated its standart eficiency
printf("Total eficiency of the board is %.2f %", ep);
pt= a*ep;
printf("Total board potential is %.2f\n", pt);
energ= (pt*radiacao[h]); // generated energy
energk=(float)energ/1000; // generated energy in kw
printf("At %d hoour, there is an average of %.2f KW/m^2 radiation\n %.2f mm of rain\n and the total energy produced by the board will be %.2f Kw \n ", hour[h], radiation[h], rain[h], energk);
printf("\n\n\n press <enter> to finish");
getchar();
}
fclose(arq);
}
#include <stdio.h>
#define efi 0.83 //83% , standart solar cell eficiency
int h,a;
int potency (int x, int y, int z)
{
return (x*y*z);
}
int hour[24], i=0;
float radiation[24], rain[24], energ,energk,pt,p,e,ep,ee;
int main()
{
FILE *arq;
arq = fopen("file2.txt", "r");
if(arq == NULL) {
printf("Error! unable to open file! \n");
getchar();
}
else {
printf("File open... \n");
printf("Reading file...\n");
while (!feof(arq)){
fscanf(arq,"%d %f %f\n", &hour[i], &radiation[i], &rain[i]);
i++;
}
printf("type board area m^2\n");
scanf("%d", &a);
printf("type maximum board pontency in WATTS/M^2\n");
scanf("%f", &p);
ep=p*efi; //Board potential after calculated its standart eficiency
printf("Total eficiency of the board is %.2f %", ep);
pt= a*ep;
printf("Total board potential is %.2f\n", pt);
int i;
for(i = 0; i < 24; i++)
{
energ= (pt*radiation[i]); // generated energy
energk=(float)energ/1000; // generated energy in kw
printf("At %d hoour, there is an average of %.2f KW/m^2 radiation\n %.2f mm of rain\n and the total energy produced by the board will be %.2f Kw \n ", i, radiation[i], rain[i], energk);
}
scanf("%d", &a);
}
fclose(arq);
}
Perform the following conversions to convert from CELSIUS to RANKINE:
degrees Fahrenheit = (9.0/5.0) * degrees Celsius + 32
degrees Rankine = degrees Fahrenheit + 459.67"
This program converts degrees Celsius to degrees Rankine. Prompt the user for a temperature in Celsius.
#include <stdio.h>
int main(void)
{
double f,c,r;
printf("Enter the temperature in degrees Celsius:" );
scanf("%d", &c);
f = (9.0/5.0) * c +32;
r = f + 459.67;
printf("After your conversion, your temperature in Rankin is: ", r);
return(0);
}
Why is my CELSIUS to RANKINE conversion failing when prompting user for a value for CELSIUS?
Code is using the incorrect type of data per the format specifiers. For type double, scan with "%lf" and to print use "%f"
#BLUEPIXY comment to use the matching format specifiers in sncaf() and printf():
Insure prompt is flushed.
Check scanf() return value.
.
#include <stdio.h>
int main(void) {
double f,c,r;
printf("Enter the temperature in degrees Celsius:" );
fflush(stdout);
if (scanf("%lf", &c) != 1) {
puts("Non-numeric input" );
return -1;
}
f = (9.0/5.0) * c +32;
printf("After your conversion, your temperature in Fahrenheit is: %.1f F", f);
r = f + 459.67;
printf("After your conversion, your temperature in Rankine is: %.1f R", r);
return 0;
}
I have been using windows all this time and recently installed Ubuntu on Virtual Box. To give Ubuntu a try,i wrote a simple calculator program.
Here's how it goes:
#include<stdio.h>
float add(float ,float ),sub(float , float ),mul(float ,float ),div(float ,float );
int main()
{
char ch;
float a,b;
printf("Enter an operator: ");
scanf("%c",&ch);
printf("Enter two values: ");
scanf("%f%f",&a,&b);
switch(ch)
{
case '+':
printf("The sum of %f and %f is %f\n",a,b,add(a,b));
break;
case '-':
printf("The substraction of %f from %f is %f\n",a,b,sub(a,b));
break;
case '*':
printf("The multiplication of %f and %f is %f\n",a,b,mul(a,b));
break;
case '/':
printf("The division of %f and %f is %f\n",a,b,div(a,b));
break;
default:
printf("\nEnter a valid operator: \n");
main();
}
return 1;
}
float add(float x,float y)
{
return (float)x + y;
}
float sub(float x,float y)
{
return (float)x-y;
}
float mul(float x,float y)
{
return (float) x*y;
}
float div(float x,float y)
{
return (float) x/y;
}
when i enter an invalid operator,it should actually read the operator and values again. But, it's asking for values directly without reading the operator. Here's a picture:
So what am i doing wrong? please explain. Thanks in advance!
You did not ignore the newlines in your inputs.
Change
scanf("%c", &ch);
to
scanf(" %c", &ch);
and try again.
When you input 3<enter>, that 3 will be consumed by the second %f, but that <enter> (i.e. newline) will still in the input buffer, and the %c in the first scanf() will consume this newline. The space in %c will ignore that newline in the input buffer.
$ ./a.out
Enter an operator: h
Enter two values: 2
3
Enter a valid operator:
Enter an operator: +
Enter two values: 2
3
The sum of 2.000000 and 3.000000 is 5.000000
I've written a special calculator which prompts the user for 2 numbers then displays a menu which basicly asks the user what to do with that input. It works great however no matter what numbers I input the result is 0. What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
int main()
{
char a, rad, patrat;
float x, y, media, radical, pat1, pat2;
patrat = 253;
rad = 251;
loop:
printf("Input 2 numbers...\n");
scanf("%f %f", &x, &y);
media = (x+y)/2;
radical = sqrt(x+y);
pat1 = x*x;
pat2 = y*y;
loop2:
printf("\n \nA - Arithmetic media.\n");
printf("B - Square root.\n");
printf("C - Sqare of the 2 numbers.\n");
printf("D - Write other numbers.\n");
printf("E - Terminate the program.\n");
a = getch();
switch(a) {
case'a':
system("cls");
printf("Media of the 2 numbers is %f", &media);
goto loop2;
case'b':
system("cls");
printf("%c%f + %f = %f", &rad, &x, &y, &radical);
goto loop2;
case'c':
system("cls");
printf("%f%c = %f, %f%c = %f", &x, &patrat, &pat1, &y, &patrat, &pat2);
goto loop2;
case'd':
goto loop;
case'e':
return 0;
}
}
You're using & in your printf statements, you shouldn't be. Scanf has it as it's writing so takes pointers.
Why are you using the operator & to your printf arguments?
printf doesn't take pointer arguments for %f conversion specification
float b;
scanf("%f", &b);
but
float a = 42;
printf("%f\n", a);
printf("Media of the 2 numbers is %f", &media);
should be
printf("Media of the 2 numbers is %f", media);
similarly for all other printf()
Generally goto statements are considered harmful when they are called backwards! So please avoid them. The same functionality can be done by a while(1) for for(;;) loop with proper termination condition.
In your printf statement, you are using
printf("Media of the 2 numbers is %f", &media);
&media is the address of your variable media.
In scanf, we provide the address of the variable as parameter so that it stores the values at that address. But in printf, we provide the variable value and not the variable address. If you provide variable address then it would print the address and not the value.
So the correction should be
printf("Media of the 2 numbers is %f", media);