C anomaly invalid output - c

I have code that needs to run some functions with arguments from stdin. First function counts factorial of argument, second one counts length and square of round with radius presented by argument. Third needs just to printf its arguments.But after my input I have very strange result. My IDE is Xcode
Input:
5
1.3
8
8
fgd
Expected output:
120
Obvod: 8.168134 Obsah: 5.309287
88fgd
Real output:
120
Obvod: 8.168134 Obsah: 5.309287
88
fg
Whats wrong with last input? Thanks a lot in advance for your answer! The whole code below:
#include <stdio.h>
#include <stdlib.h>
int factorial (int value)
{
int fac = value;
if (value == 0)
{
return 1;
}
else if (value < 0)
{
return 0;
}
for (int i = 1; i < value; i++)
{
fac *= value - i;
}
return fac;
}
void radius (float rad, float* lep, float* sqp)
{
const float pi = 3.14159;
if (rad < 0)
{
printf("Obvod: 0 Obsah: 0\n");
}
float lenght = 2 * pi * rad;
float square = pi * (rad * rad);
*lep = lenght;
*sqp = square;
printf("Obvod: %f Obsah: %f\n", lenght, square);
}
void read_array_data(int h, int w, char x1, char x2, char x3)
{
printf("%i%i%c%c%c\n", h, w, x1, x2, x3);
}
int main()
{
char c1;
char c2;
char c3;
int f, height, width;
float r;
float radius_container, square_container;
float* p1 = &radius_container;
float* p2 = &square_container;
scanf("%i", &f);
scanf("%f", &r);
scanf("%i", &height);
scanf("%i", &width);
scanf("%c%c%c", &c1, &c2, &c3);
printf("%i\n", factorial(f));
radius(r, p1, p2);
read_array_data(height, width, c1, c2, c3);
}

scanf(" %c%c%c", &c1, &c2, &c3);
// ^^^ insert space here
When you hit Enter from the previous scanf, a newline is left in stdin. That newline is read into c1, the f into c2, and finally g into c3. When you print, the newline prints dropping to the next line, followed by fg. The leading space tells scanf to skip that leading whitespace. After that, the fgd characters will be read into c1, c2, c3 as you expect.
Demonstration
See scanf("%c") call seems to be skipped for more info

Related

Not able to find my segmentation fault in this code of t-test

I have written this program for t-test. I'll add other functions as well, but first, I need to find my error. Here's my code
# include <stdio.h>
# include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
int input(n)
{
float x[n];
printf("Enter the values one by one");
for (int i = 0; i<n;i++)
scanf("%f", &x[i]);
return x;
}
void t_check(float x)// Make sure to write this function before each of the t-tests. That is because it is of void type. If the t-test is done before the checking function is declared, then it assumes it's datatype to be "int", and we get an error. So either write the t-check function before those functions, or just define it at the beginning of the program
{
float t_tab;
printf("Enter the tabulated value of t");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis");
else
printf("Reject the null hypothesis");
}
float t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0,tcal;
int n,m,a,b;
printf("Enter the number of variables in population 1");
scanf("%d", &n);
a = input(n);
printf("Enter the number of variables in population 2");
scanf("%d", &m);
b = input(m);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
It gives segmentation fault as an error. I'm not able to understand where my code uses any memory uses a part of memory that is not allocated to it
The main issue is you expect input() to read an array floats but you return an int. You should declare the type of the argument n. You cannot return an address to a local variable as it out of scope for caller. The easiest option is to the declare the array variable in main() then pass it to input to populate (pun). (not fixed) Check that return value of scanf() otherwise the variable you expect to be initialized may not be.
t_diff_of_means() is declared to return a float but nothing is returned. Not sure what you want to return so I changed the return type to void.
Tweaked various prompts to make it more them more readable.
#include <stdio.h>
#include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
void input(size_t n, float a[n])
{
printf("Enter the values one by one: ");
for (int i = 0; i<n;i++)
scanf("%f", a+i);
}
void t_check(float x)
{
float t_tab;
printf("Enter the tabulated value of t: ");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
void t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0;
int n,m;
printf("Enter the number of variables in population 1: ");
scanf("%d", &n);
float a[n];
input(n, a);
printf("Enter the number of variables in population 2: ");
scanf("%d", &m);
float b[m];
input(m, b);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
and example run:
Enter the number of variables in population 1: 2
Enter the values one by one: 1
2
Enter the number of variables in population 2: 2
Enter the values one by one: 2
3
Enter the tabulated value of t: 0.05
We do not have enough evidence to reject the null hypothesis
Consider eliminating the variables you only use once (x, y, s1, s2, S, t and t_cal):
t_check(
(mean(a, n) - mean(b, m)) / (sqrt((sumsq(a, n)+sumsq(b, m))/(n+m-2))*sqrt(1.0/n+1.0/m))
);
then I observed that this only depends on variables a, n, b and m so push that calculation into t_check():
void t_check(size_t a_len, float a[a_len], size_t b_len, float b[b_len]) {
float t = (mean(a, a_len) - mean(b, b_len)) / (sqrt((sumsq(a, a_len)+sumsq(b, b_len))/(a_len+b_len-2))*sqrt(1.0/a_len+1.0/b_len));
// ...
}
Then I changed the length types to size_t and used the clearer variable names in t_diff_of_means():
void t_diff_of_means()
{
printf("Enter the number of variables in population 1: ");
size_t a_len;
scanf("%zu", &a_len);
float a[a_len];
input(a_len, a);
printf("Enter the number of variables in population 2: ");
size_t b_len;
scanf("%zu", &b_len);
float b[b_len];
input(b_len, b);
t_check(a_len, a, b_len, b);
}
We could take this another step by observing the two first sections in t_diff_of_means() are very similar, so we could have input() take a prompt and a pointer to an array of floats along with elements read. input() would then need to dynamically allocate the array of floats. This means most of our functions take a array of float and length argument. Let's create a type for that and refactor our functions to use it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct array {
size_t len;
float *data;
};
float mean(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += a->data[i];
return sum/a->len;
}
float sumsq(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += pow(a->data[i] - mean(a), 2);
return sum;
}
void input(int prompt, struct array *a)
{
printf("Enter the number of variables in population %d: ", prompt);
scanf("%zu", &a->len);
a->data = malloc(a->len * sizeof(a->data[0]));
//if(!a->data) ...
printf("Enter the values one by one: ");
for (int i = 0; i<a->len;i++)
scanf("%f", &a->data[i]);
}
void t_check(struct array a[2])
{
float t = (mean(a) - mean(a+1)) / (
sqrt(
(sumsq(a) + sumsq(a+1)) / (a[0].len + a[1].len-2)
) * sqrt(1.0/a[0].len + 1.0/a[1].len)
);
printf("Enter the tabulated value of t: ");
float t_tab;
scanf("%f",&t_tab);
if (t<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
int main(void)
{
struct array a[2];
input(1, a);
input(2, a+1);
t_check(a);
}
This would be a good base to add additional functions to.

Implementing two sample t-test in C

I am making a function that will calculate the test statistic from a two sample t-test and return it's value. However, I have been getting incorrect results. I previously was using scanf and got good answers, but it randomly stopped working. So I decided to switch to fgets which is suppose to be more reliable, however, the values it's returning are incorrect.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define VAL 10
double tstat(int x1,int x2,int s1,int s2,int n1,int n2);
int main()
{
char mean1[VAL] = {0};
char sd1[VAL] = {0};
char n1[VAL] = {0};
char mean2[VAL] = {0};
char sd2[VAL] = {0};
char n2[VAL] = {0};
printf("Enter mean 1: \n");
fgets(mean1, 10, stdin);
printf("Enter sd 1: \n");
fgets(sd1, 10, stdin);
printf("Enter sample size 1: \n");
fgets(n1, 10, stdin);
printf("Enter mean 2: \n");
fgets(mean2, 10, stdin);
printf("Enter sd 2: \n");
fgets(sd2, 10, stdin);
printf("Enter n2: \n");
fgets(n2, 10, stdin);
printf("t value is: %lf", tstat(atoi(mean1),atoi(mean2),atoi(sd1),atoi(sd2),atoi(n1),atoi(n2)));
}
double tstat(int x1,int x2,int s1,int s2,int n1,int n2)
{
double t = 0;
t = (x1 - x2)/(sqrt(pow(s1,2)/n1+pow(s2,2)/n2));
return t;
}
For example, setting mean1 = 1.3, sd1 = 0.5, n1 = 22; mean2 = 1.6,sd2 = 0.3, n2 = 24 should yield a value of -2.44, however, plugging this in returns -1 followed by #IND00. I presume my issue is that either I am misinterpreting how to properly use fgets, or something is going wonky with the datatypes, though I am a beginner in C, and I have not been able to spot any clear errors.
Your variables are all of type int and you're using atoi to convert the strings to int. However, the values you're entering aren't integers, they're floating point values, so only the integer part of each number is interpreted. For example, atoi("1.3") results in 1.
You need to change your datatypes to double and use atof instead.
double tstat(double x1, double x2, double s1, double s2, double n1, double n2)
{
double t = 0;
t = (x1 - x2)/(sqrt(pow(s1,2)/n1+pow(s2,2)/n2));
return t;
}
...
printf("t value is: %lf", tstat(atof(mean1),atof(mean2),atof(sd1),atof(sd2),atof(n1),atof(n2)));

Using a loop to run a program n amount of times

I am new to the C programming language. I am attempting to run the code below an N amount of times (based on the user input of "Enter amount of iterations"). I am trying to do this using a for loop (also tried with a while loop) but have been unsuccessful.
Whenever I run the code below, my terminal continuously repeats "Enter two float numbers:". I have to close the terminal and reopen it to try again. Does the issue have to do with my for loop? I am interpreting my for loop as: "a=0; if a > 0; increment a". Is there a way I can set a limit for "if a > 0" or should I be using a while loop? If the user enters "3" for amount of iterations, I am expecting the program to ask "Enter two float numbers" 3 times (with the answer).
float sum (float m, float n){
return m+n;}
int main() {
float x, y;
int a;
printf("Enter amount of iterations: ");
scanf("%d", &a);
for (int i; i < 0; i++) {
printf("Enter two float numbers: ");
scanf("%f %f", &x, &y);
float su = sum(x,y);
printf("%f and %f = ", x, y);
printf("%f\n", su);}
return 0;}
CORRECT ANSWER Formatted for readability:
float sum(float m, float n)
{
return m + n;
}
int main()
{
float x, y;
int a;
printf("Enter amount of iterations: ");
scanf("%d", &a);
for (int i = 0; i < a; i++)
{
printf("Enter two float numbers: ");
scanf("%f %f", &x, &y);
float su = sum(x, y);
printf("%f and %f = ", x, y);
printf("%f\n", su);
}
return 0;
}
This should behave more like you would like it to:
#include <stdio.h>
static float sum(float m, float n)
{
return m + n;
}
int main(void)
{
float x, y;
int a;
printf("Enter amount of iterations: ");
if (scanf("%d", &a) != 1)
{
fprintf(stderr, "Invalid input for iterations\n");
return 1;
}
for (int i = 0; i < a; i++)
{
printf("Enter two float numbers: ");
if (scanf("%f %f", &x, &y) != 2)
{
fprintf(stderr, "Failed to read to floating point numbers\n");
return 1;
}
float su = sum(x, y);
printf("%f and %f = ", x, y);
printf("%f\n", su);
}
return 0;
}
Note that it checks that the input operations are successful, and reports errors on standard error (stderr). The code uses a standard C for loop to count from 0 up to a limit — this is idiomatic C. You should get used to using it.
As I noted in a comment, the a in the for loop is different from and unrelated to the a declared earlier in your code and set by the input operation. The a in the for loop is not initialized; you can't tell how many times the loop will be executed. A good compiler should warn you about redefining or shadowing a.
for (i = 0; i < a; i++); - answer provided by J.S!

Program that finds y, derivative, and integral vals of a polynomial (UPDATED)

Making a program that should calculate a polynomials y values derivative and integral... Right now having problems formatting the for loop so it cycles through all the x values I want it to (as determined by user).
Pretty sure the math func isnt fully correct right now too but I can go at them later once i get this loop working haha
heres my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void explain();
void math(double a, double b, double c, double x, double xi, double *fx, double *fD, double *A);
int main()
{
double a, b, c;
double xi, xf, xc, x=0;
double fx=0, fD=0, A=0;
printf("SECOND DEGREE POLYNOMIAL CALCULATOR\n\n");
explain();
printf("\n\nEnter a value for a: ");
scanf("%lg", &a);
printf("Enter a value for b: ");
scanf("%lg", &b);
printf("Enter a value for c: ");
scanf("%lg", &c);
printf("\nYour function is %lgx^2%+-lgx%+-lg", a, b, c);
printf("\n\nEnter your initial x-value: ");
scanf("%lg", &xi);
printf("Enter your final x-value: ");
scanf("%lg", &xf);
printf("Enter what you would like to increment by: ");
scanf("%lg", &xc);
printf("| x | f(x) | f'(x) | A |\n"); //printing table
printf("----------------------------------------\n");
for(int i=xi; i<xf; i++) {
math(a, b, c, x, xi, &fx, &fD, &A);
printf("| %.3lf | %.3lf | %.3lf | %.3lf |\n", x, fx, fD, A);
x = x + xc;
}
return;
}
void explain() {
printf("This program computes the integral and derivative of a user inputted second-degree polynomial (f(x)=ax^2+bx+c).\n");
printf("You will be asked to enter the 3 coefficients of your polynomial, followed by your initial x-value, your\n");
printf("final x-value, and the increment value between each x.");
}
void math(double a, double b, double c, double x, double xi, double *fx, double *fD, double *A) {
*fx = (a*(x*x)) + (b*x) + c; //finding y values
*fD = (2*a) + b; //finding derivative values
*A = ((a/3)*pow(x,3) + (a/2)*pow(x,2) + c*x) - ((a/3)*pow(xi,3) + (a/2)*pow(xi,2) + c*xi); //finding integral values
return;
}
Heres a screenshot of the output, as you can see the table is printing only till 1 instead of 5 like wanted (indicated by inputs). I need to change whats in the for loop to get it to output right but Im not sure what to do
I saw some problem with your code:
1> Your derivation function is not correct. should be 2*a*x + b
2> I change the for loop to while loop with step is xc inputed from stdin
Here is my solution with your newest answer:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void explain();
void math(double a, double b, double c, double x, double xi, double *fx, double *fD, double *A);
int main()
{
double a, b, c;
double xi, xf, xc, x = 0;
double fx = 0, fD = 0, A = 0;
printf("SECOND DEGREE POLYNOMIAL CALCULATOR\n\n");
explain();
printf("\n\nEnter a value for a: ");
scanf("%lg", &a);
printf("Enter a value for b: ");
scanf("%lg", &b);
printf("Enter a value for c: ");
scanf("%lg", &c);
printf("\nYour function is %lgx^2%+-lgx%+-lg", a, b, c);
printf("\n\nEnter your initial x-value: ");
scanf("%lg", &xi);
printf("Enter your final x-value: ");
scanf("%lg", &xf);
printf("Enter what you would like to increment by: ");
scanf("%lg", &xc);
printf("| x | f(x) | f'(x) | A |\n"); //printing table
printf("----------------------------------------\n");
x = xi;
double nextX;
while (x <= xf) {
nextX = x + xc;
math(a, b, c, x, nextX, &fx, &fD, &A);
printf("| %.3lf | %.3lf | %.3lf | %.3lf |\n", x, fx, fD, A);
x = x + xc;
}
return 0;
}
void explain() {
printf("This program computes the integral and derivative of a user inputted second-degree polynomial (f(x)=ax^2+bx+c).\n");
printf("You will be asked to enter the 3 coefficients of your polynomial, followed by your initial x-value, your\n");
printf("final x-value, and the increment value between each x.");
}
void math(double a, double b, double c, double x, double xi, double *fx, double *fD, double *A) {
*fx = (a*(x*x)) + (b*x) + c; //finding y values
*fD = (2 * a * x) + b; //finding derivative values
*A = ((a / 3)*pow(x, 3) + (a / 2)*pow(x, 2) + c * x) - ((a / 3)*pow(xi, 3) + (a / 2)*pow(xi, 2) + c * xi); //finding integral values
return;
}

How to make compiler repeat until the number 0 is presed

I'm wondering how to make the compiler repeat itself if the user presses a random button at the end. But if the user presses "0" the compiler exits.
My code:
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
#include <float.h>
struct mystruct
{
float startnummer;
float hoppnummer;
float svarighetsgrad;
float domarpoangs[7];
};
int main(void)
{
struct mystruct data;
float max = 0;
float min = FLT_MAX;
float sum = 0;
float avg = 0;
int i = 0;
float resultat = 0;
printf("Startnummer: \n");
scanf_s("%f", &data.startnummer);
printf("Hoppnummer:\n");
scanf_s("%f", &data.hoppnummer);
printf("Svarighetsgrad:\n");
scanf_s("%f", &data.svarighetsgrad);
for (i = 0; i < 7; i++)
{
printf("domarpoang %d\n", i + 1);
float f;
if (scanf_s("%f", &f) == 1)
{
if (f < min) min = f;
if (f > max) max = f;
data.domarpoangs[i] = f;
}
else
{
printf("error parsing float\n");
exit(0);
}
}
system("cls");
printf("Startnummer: %.1f \n", data.startnummer);
printf("Hoppnummer: %.1f\n", data.hoppnummer);
printf("Svarighetsgrad: %.1f\n", data.svarighetsgrad);
for (i = 0; i < 7; i++)
{
printf("Domarpoang %d: %.1f\n", (i + 1), data.domarpoangs[i]);
}
for (i = 0; i < 7; i++)
{
sum += data.domarpoangs[i];
}
sum = sum - (max + min);
avg = sum/5;
resultat = avg * 3 * data.svarighetsgrad;
printf("Hoppoang:%.2f \n", resultat);
printf("Tryck tangent for nytt hopp!");
getchar();
getchar();
return 0;
}
*If the user presses random button, the compiler repeat itself from the beginning
*If the user presses 0, the compiler exits.
Any help is appreciated, thank you.
This answer puts a loop around the body of your main() code, taking care to re-initialise some of the variables for the next iteration.
There are many SO questions about getting keyboard input and clearing the debris. I know of no simple standard ways of testing for keyboard input such as kbhit(), for taking a single key input such as getch() or for flushing the input. Even getchar() is horrible - it won't return until you have pressed "Enter" which it leaves in the input buffer. This has resulted in many SO answers with impenetrable (to me) formats for scanf() to flush the input, or testing if (getchar() == EOF) - which does not respond to the "Enter" key.
So I have put a simple wrapper around the main() code, which terminates when '0' is entered followed by a control char (because fgets() appends the newline) or terminator. This removes the need to clean up the input - except in the case where the user inputs some silly typing. GIGO!
#include <stdio.h>
#include <float.h>
#define BUFFSIZE 10
struct mystruct {
float startnummer;
float hoppnummer;
float svarighetsgrad;
float domarpoangs[7];
};
int main(void)
{
char kbuff [BUFFSIZE+1];
struct mystruct data;
float max;
float min;
float sum;
float avg;
int i;
float resultat;
do {
max = 0; // initialise for each loop
min = FLT_MAX;
sum = 0;
printf ("Body of your main loop\n");
fgets(kbuff, BUFFSIZE, stdin);
} while (kbuff[0] != '0' || kbuff[1] >= ' ');
return 0;
}

Resources