I'm learning C and found this code on a tutorial and it works fine, but if I try to make a decimal number (like 5.5), it prints a negative one in the following arrays and loops itself.
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <math.h>
#include "stdafx.h"
#define ARBEITER 3
#define TAGE 5
#define ARBEITSKALENDER kalender();
int zeitkonto[ARBEITER][TAGE];
/* Fehlerausgabe */
void error(int n) {
printf("%d (?) Falsche Eingabe!!\n", n);
}
ABFRAGE0: {
int i = 0, j = 0;
for (i = 0; i < TAGE; i++) {
printf("\n\t[Eingeloggt als: %s ] Tag %d in der Woche\n", vorname, i + 1);
printf("\t-------------------\n\n");
for (j = 0; j < ARBEITER; j++) {
printf("Arbeiter Nr.%d in Std.: ", j + 1);
scanf("%ld", &zeitkonto[j][i]);
if (zeitkonto[j][i] > 24) {
printf("Ein Tag hat nur 24 Stunden?\n");
PCLEAR WHALLOWELT ABSATZ goto ABFRAGE0;
}
if (zeitkonto[j][i] > 47) {
printf("Wer wünscht sich nicht, man hätte mehr Zeit?");
PCLEAR WHALLOWELT ABSATZ goto ABFRAGE0;
}
}
}
}
What am I doing wrong?
If you want floating point numbers in zeitkonto, replace :
int zeitkonto[ARBEITER][TAGE];
by
double zeitkonto[ARBEITER][TAGE];
and replace
scanf("%ld", &zeitkonto[j][i]);
by
scanf("%f", &zeitkonto[j][i]);
and also replace any
printf("...%ld...", zeitkonto[...][...]) ;
by
printf("...%f...", zeitkonto[...][...]) ;
I'm guessing it's the scanf in the kalender function you have problem with.
If you read scanf you will see that the function returns the number of successfully scanned items. In your case, it will return one, zero or EOF.
If scanf returns one, you successfully read an integer. If it returns EOF the user pressed the end-of-file key combination (or there was another error). The case you really have to look out for is when scanf returns zero, which will happen if you enter something unexpected, like a floating point value. If scanf fails (when it returns zero or EOF) it will not change the value of the variable.
The question have been edited, and I see that I was focusing on the wrong scanf. However, my answer (including the hints on how to solve the problem) is still valid.
If you do want to be able to read floating point numbers, you should of course change the format to "%f" or "%lf", and you must also change the array base type from int to float or double.
zeitkonto is an array of integers - whole numbers. You need fractional numbers, in particular floating point. That means using double and %lf to read them.
Related
Why is this code not running after printing of array if I take value of n>=9?
#include <stdio.h>
#include <math.h>
float mean_function(float array[],int n);
int main() {
int i,n;
float array[n],mean,sum=0,s2,summation,deno,C[i],elements;
printf("Enter No of Elements\n");
scanf("%d",&n);
printf("Enter Elements\n");
for(i=0;i<n;i++){
scanf("%f",&array[i]);
printf("%f",array[i]);
}
printf("sample variance(s2) : (sum((x-mean)*(x-mean)))/(n-1) /n");
printf("population variance(sigma2) : (sum((x-u)*(x-u))/n");
mean_function(array,n);
for(i=0;i<n;i++) {
deno=((array[i]-mean)*(array[i]-mean));
C[i]=deno;
summation=summation+C[i];
}
s2=((summation)/(n-1));
printf("s2=%f \n",s2);
}
float mean_function(float array[],int n) {
int i;
float sum=0,mean;
for(i=0;i<n;i++){ sum=sum+array[i]; }
mean=(sum/n);
return mean;
}
Why is this code not running after printing of array if I take value
of n>=9?
Some thoughts about your code (and about building programs in steps):
Arrays in C don't change in size once defined. VLAs are out for a variety of reasons. malloc() is in.
Use double, unless there is a specific reason to use floats.
Define and initialize one variable per line. Uninit vars can only result in an error as mentioned by #Jens.
Function declarations at the top (which you have done)
During development, there is no need to complicate things with a scanf (at least initially). It only adds an unwarranted layer of complexity. If you are testing statistical functions (mean, variance), put numbers in a pre-defined static array and verify functionality first.
C[i] as been declared with uninitialized i.
For this initial phase of building this program, I include a basic program.
I am not a fan of zero space between tokens (but ignore that)
Consider calling your array something other than 'array'.
Calculating the size of the samples array allows you to change the number of elements without changing anything else in code; which adds another layer of complexity to an already difficult phase.
#include <stdio.h>
#include <math.h>
double sample_mean(double* p, int n);
int main()
{
double samples[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 16.5, 2.3};
double mean = 0.0;
int size_samples = sizeof samples/sizeof(double);
printf("size_samples = %d\n", size_samples);
mean = sample_mean(samples, size_samples);
printf("Mean = %.2lf", mean);
}
// -------------------------------
double sample_mean(double* p, int n)
{
double mean = 0.0;
double total = 0.0;
for(int i = 0; i < n; i++)
total += *p++;
mean = total/n;
return mean;
}
Once this functionality is present (saved), you can start working on other stat functions. This way you can work step by step to get closer to the desired outcome.
Next up you can define sample_variance(double* p, int n) and work on that knowing that additional(new errors) are not coming from your code written so far.
Output:
size_samples = 8
Mean = 5.24
I hope it helps.
The code is likely not running because array[n] is declared with an uninitialized n. At the time you read n with scanf(), the array does not automatically "grow into the right size". You should either declare array big enough, or if you really want it to be user-defined, use malloc to allocate it (read the comp.lang.c FAQ) and all Stackoverflow questions tagged array...)
In addition, the scanf at some point fails. Note that when you enter numbers, you also have the "Enter" as a newline ('\n') in the input stream. You never read the newline so the next scanf fails.
This becomes obvious when you actually check the return value from scanf with code like this:
if (scanf("%f", &array[i]) == 1) {
/* successfully converted 1 item */
}
else {
/* scanf failed */
}
Usually what you want is to skip whitespace in the input. You do this by placing a space in the scanf format. Note that a single space tells scanf to skip any amount of white-space.
if (scanf(" %f", &array[i]) == 1) {
I'm trying to run a program that does certain operations on factorials of large numbers (say 50!; viz 3.041e+64 - huge!) and therefore doesn't fit in the normal int data types that I'm aware of(unsigned long long int etc)
Which data type do I use to store these values?
P.S I was trying to find the trailing zeroes in a factorial. The following was my approach:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int FactorialFinder(int a)
{
if (a>1)
a= a* (FactorialFinder(a-1)) ;
return a;
}
int main()
{
printf("Enter number \n");
int num ;
scanf("%d",&num) ;
printf("number is %d\n",num);
printf("Factorial is %d",(num = FactorialFinder(num))) ;
int x=0, count = 0 ;
while(num>0)
{
x = (num%10) ;
if (x == 0)
count++ ;
else
break;
num= num/10 ;
}
printf("\nNumber of trailing zeroes is %d",count) ;
getchar() ;
return 0;
}
Works fine upto 12! beyond which the results are erroneous (from 17! it starts returning negative factorial values(?), from 34! it gives 0) I'm guessing due to the datatype problem. Can someone help me out?
Well these kind of numbers cannot be stored as single number rightly as you've reasoned there are no data types to hold them. The best way to work with large numbers is to store them as arrays of int type or char type.
for example you can store 1234567898765 as an array int big[14] where,
big[0]=1
big[1]=2
.
.
.
big[13]=5 //last element
big[14]=-1 //to mark the end of number...
or in the reverse order with -1 as last element (select which is is convenient for your implementation)
and now comes the challenging part where you have to create functions for addition, subtraction, multiplication and other operations which you require.. There are many ways of implementing these function..give a try.. or you can just look up how to do them here's a source : click
this provides a implementation of arithmetic numbers for up to 100 digit numbers however you can try to build one which can deal with even larger numbers :)
Here is the problem: The game Totals can be played by any number of people. It starts with a total of 100 and each player in turn makes an integer displacement between -20 and 20 to that total. The winner is the player whose adjustment makes the total equal to 5. Using only the three variables given:
total
adjustment
counter
Here is what I have so far:
#include <stdio.h>
int main (void)
{
int counter=0;
float adj;
int ttl=100;
printf("You all know the rules now lets begin!!!\n\n\nWe start with 100. What is\n");
while (ttl!=5)
{
printf("YOUR ADJUSTMENT?");
scanf("%f",&adj);
counter++;
if (adj<=20 && adj>=-20)
{
ttl=ttl+adj;
printf("The total is %d\n",ttl);
}
else
{
printf ("I'm sorry. Do you not know the rules?\n");
}
}
printf("The game is won in %d steps!",counter);
}
What I need:
When a decimal number is entered it goes to the else. How do I determine if a float has a fractional part.
You can cast the float to an int and then compare it to your original variable. If they are the same there was no fractional part.
By using this method, there is no need for a temporary variable or a function call.
float adj;
....
if (adj == (int)adj)
printf ("no fractional!\n");
else
printf ("fractional!\n");
Explanation
Since an int cannot handle fractions the value of your float will be truncated into an int (as an example (float)14.3 will be truncated into (int)14).
When comparing 14 to 14.3 it's obvious that they are not the same value, and therefore "fractional!" will be printed.
#include <stdio.h>
#include <math.h>
int main ()
{
float param, fractpart, intpart;
param = 3.14159265;
fractpart = modff (param , &intpart);
return 0;
}
http://www.cplusplus.com/reference/clibrary/cmath/modf/
modff finds the fractional part, so I guess testing whether it's equal to 0 or null will answer your question.
if you want to know whether a real number x has no fractional part, try x==floor(x).
I am only learning C so tell me if I am wrong, please.
But if instead of using
scanf("%f",&adj);
if you use:
scanf("%d%d", &adj, &IsUndef);
Therefore if the user typed anything other than a whole integer &IsUndef would not equal NULL and must have a fractional part sending the user to else.
maybe.
Using scanf() is problematic. If the user typed -5 +10 -15 -15 on the first line of input, then hit return, you'd process the 4 numbers in turn with scanf(). This is likely not what you wanted. Also, of course, if the user types +3 or more, then the first conversion stops once the space is read, and all subsequent conversions fail on the o or or, and the code goes into a loop. You must check the return value from scanf() to know whether it was able to convert anything.
The read-ahead problems are sufficiently severe that I'd go for the quasi-standard alternative of using fgets() to read a line of data, and then using sscanf() (that extra s is all important) to parse a number.
To determine whether a floating point number has a fractional part as well as an integer part, you could use the modf() or modff() function - the latter since your adj is a float:
#include <math.h>
double modf(double x, double *iptr);
float modff(float value, float *iptr);
The return value is the signed fractional part of x; the value in iptr is the integer part. Note that modff() may not be available in compilers (runtime libraries) that do not support C99. In that case, you may have to use double and modf(). However, it is probably as simple to restrict the user to entering integers with %d format and an integer type for adj; that's what I'd have done from the start.
Another point of detail: do you really want to count invalid numbers in the total number of attempts?
#include <stdio.h>
#include <math.h>
int main(void)
{
int counter=0;
int ttl=100;
printf("You all know the rules now lets begin!!!\n"
"\n\nWe start with 100. What is\n");
while (ttl != 5)
{
char buffer[4096];
float a_int;
float adj;
printf("YOUR ADJUSTMENT?");
if (fgets(buffer, sizeof(buffer), stdin) == 0)
break;
if (sscanf("%f", &adj) != 1)
break;
if (adj<=20 && adj>=-20 && modff(adj, &a_int) == 0.0)
{
counter++; // Not counting invalid numbers
ttl += adj;
printf("The total is %d\n", ttl);
}
else
{
printf ("I'm sorry. Do you not know the rules?\n");
}
}
if (ttl == 5)
printf("The game is won in %d steps!\n", counter);
else
printf("No-one wins; the total is not 5\n");
return(0);
}
Clearly, I'm studiously ignoring the possibility that someone might type in more than 4095 characters before typing return.
This is a homework project I was assigned some time ago... I've been successful in getting this far on my own, and the only hiccup I have left is (I believe) an issue with data types and overflow.
I've tried changing over to unsigned and double, and the code complies and still accepts input in the terminal, but it seems to hang up after that... nothing is printed and it looks like it's caught in a loop.
Here is the code...
/* pascaltri.c
* A program that takes a single integer as input and returns the nth line of
* Pascal's Triangle. Uses factorial() function to help find items of
* individual entries on a given row.
*/
#include <stdio.h>
#include <stdlib.h>
long factorial(long i)
{
long fact = 1;
while(i > 1)
{
fact = fact * i;
i = i - 1;
}
return fact;
}
main(void)
{
long n;
long *nPtr;
nPtr = &n;
scanf(" %i", nPtr);
if (n >= 0)
{
long k;
long *kPtr;
kPtr = &k;
for(k = 0; k <= n; k++)
{
long ans;
long *ansPtr;
ansPtr = &ans;
ans = factorial(n) / (factorial(k) * factorial(n - k));
printf("\n %i", ans);
}
return 0;
}
return 0;
}
It's not perfect or pretty, but it works up to an input of 13 (that is, row 14) of the triangle. Beyond that I start getting gibberish and even negative values sprinkled throughout the returns... much larger values break the code and return nothing but an exit error message.
Any ideas on how I can correct this problem? I've been staring at the screen for much to long to really see anything myself. Also, it's not essential, but I would like to print my return values on one line, rather than having them separated by a newline character.
1 5 10 10 5 1
Would the easiest way be to load the values into an array as they are computed, and then print the array? Or is there a built-in way I can tell the print statement to occur on only one line?
You are suffering from integer overflow. You may need to find a different approach to the algorithm to avoid having to calculate the large numbers.
In answer to your other point about the newline, you are explicitly printing the newline with the \n in your print statement. Remove it, and you will get answers printed on one line. You probably want to inlucde a final printf("\n"); at the end so the whole line is terminated in a newline.
Some other observations:
You don't need the first return 0; - the control will drop out of
the bottom of the if block and on to the second (should be only)
return 0; and not cause any problems.
You're declaring kPtr but not using it anywhere
You don't need to declare a separate variable nPtr to pass to scanf; you can pass &n directly.
For the garbage, you are most likely running into an integer overflow, that is, your calculated values become too large for the long data type. You should correct it by calculating your factorial function without explicitely calculating n!.
Change scanf(" %i", nPtr); to
scanf(" %ld", nPtr);
and printf("\n %i", ans); to
printf("\n %ld", ans);
to get printout on one line, use:
printf(" %ld", ans);
If you are using gcc, turn on warnings, i.e. use -Wall.
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