C Programming - Class project - c

http://pastebin.com/uws2Ts96 - my program so far
I'm attempting to write a C program for my class where the program will display a menu giving 3 options, option 1 will lead to the function named ExtractLargestDigit, and option 2 will lead to DigitOccurrence, and option 3 will end the program.
The problem I'm having is that i want to make it so if the user enters any value other than 1 2 or 3 the program will print out WRONG OPTION and reprint out the menu and ask for another option.
I thought the way I was going about it was correct but every time I run the program it crashes. I believe there's a problem with my while loop.
I also am having problems with the 2 functions:
For the first function I want to have the user enter in a number, for example 123456, and have the program go through each digit of the number and print out the largest digit, and at what position did it occur in the number. For example in this number (123456) the largest digit is 6 and it is in the ones digit position.
For the second function I want the user to enter in 2 numbers (123423) and (452313) and have the program break the numbers down into their digits, assign them to an array, count the number of times each digit occurs and print out a list from 1-0 with the number of times the number occur along side it.
Any thoughts on these problems would be greatly appreciated.

You must pass the address of the variable using & to scanf:
scanf("%d", &option);
That's why it crashes when you run it.

You're using the assignment operator (=) as opposed to the comparison operator (==) in four of your while conditions:
while(option = 0) should be while(option == 0)
You also shouldn't have a ; straight after the condition, otherwise if the condition is true it'll always be true and you'll have an infinite loop.
while(option == 0); { ... } should be while(option == 0) { ... }
Otherwise the body of the loops aren't actually the body of the loops, they're completely unrelated to the loop.
Also, scanf("%d", option); will treat the value of option (0) as an address and try to store the inputted integer into the wrong spot of memory, causing undefined behaviour (most likely a crash). If it doesn't crash, option will remain as 0.
You should also check the return value of scanf to ensure that the right amount of items were inputted. That may also involve getting rid of any junk input up until the next newline (or EOF).
I also don't understand why you have all of those while loops. If you're trying to create a menu that loops, have one single loop where the termination condition is the option that indicates exit (in your case it looks like that's 3). You could have a switch statement inside that single loop to call the right function based on the value of option.
And a return; isn't necessary at the end of a void function.
EDIT: About those two functions, the common way of splitting a number into it's digits is:
WHILE num IS NOT 0:
digit = num MOD base
num = num DIV base
Since decimal is base 10, you'd compute the modulus (% in C) and division of num with 10. If you wanted binary digits, you'd use a base of 2. Then just do whatever you need to with each digit at every iteration. The digits will obviously be extracted starting from the end (least significant digit).
Lastly, turn up the warnings on your compiler so it'll tell you about the problems above, ie:
gcc -Wall -o test test.c
test.c: In function ‘displayProgramMenu’:
test.c:44:2: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat]
test.c:46:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
test.c:48:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
test.c:49:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
test.c:50:2: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
And (lastly + 1) you can get rid of conio.h and replace getch() with getchar() or getc(stdin).

Related

Data Structures: Infix to Prefix LinkedList(LL)

My code is able to compile and run, however the process returns -1. I have drawn out various test cases manually and believes it works, so I am not sure which part of my logic is wrong.
I ask the user for a infix exp., and in2PreLL will
reverse the infix exp.
insert it into the front of Linked List inExpLL or Stack s based on the switch-case statements
Finally, I reverse the entire inExpLL to get the prefix exp.
This code assumes:
input string consists only positive integer numbers
Only operators are + - * / ( )
I entered the input of (1+2)+(3-4), expecting a prefix exp. of ++12-34 when I draw out the process manually. However, when I run the code, it gives me Process returned -1 (0xFFFFFFFF)
EDIT:
I have debugged my code and it works now! Thanks for the suggestions everyone!
Warnings are not to be ignored:
...
default: //operand
insertNode(inExpLL, atoi(c), OPERAND);
...
My compiler croaks with
incompatible integer to pointer conversion passing 'char' to parameter of type 'const char *'
And indeed atoi(c) is plain wrong here. To convert a single digit to its numeric value, you should use c - '0'.
Even worse, your code uses the deprecated gets and uses it badly: it should at least be:
gets(infix, stdin);
Finally: you really should learn how to use a debugger...
With the added code and my 2 fixes, the code gives :
4 3 + 2 1 + ) + )
so still the closing paren to remove and the opposite order...

Recursive function for finding factorial of a number

I am getting an output of 24 which is the factorial for 4, but I should be getting the output for 5 factorial which is 120
#include <stdio.h>
int factorial(int number){
if(number==1){
return number;
}
return number*factorial(--number);
}
int main(){
int a=factorial(5);
printf("%d",a);
}
Your program suffers from undefined behavior.
In the first call to factorial(5), where you have
return number * factorial(--number);
you imagine that this is going to compute
5 * factorial(4);
But that's not guaranteed!
What if the compiler looks at it in a different order?
What it if works on the right-hand side first?
What if it first does the equivalent of:
temporary_result = factorial(--number);
and then does the multiplication:
return number * temporary_result;
If the compiler does it in that order, then temporary_result will be factorial(4), and it'll return 4 times that, which won't be 5!. Basically, if the compiler does it in that order -- and it might! -- then number gets decremented "too soon".
You might not have imagined that the compiler could do things this way.
You might have imagined that the expression would always be "parsed left to right".
But those imaginations are not correct.
(See also this answer for more discussion on order of evaluation.)
I said that the expression causes "undefined behavior", and this expression is a classic example. What makes this expression undefined is that there's a little too much going on inside it.
The problem with the expression
return number * factorial(--number);
is that the variable number is having its value used within it, and that same variable number is also being modified within it. And this pattern is, basically, poison.
Let's label the two spots where number appears, so that we can talk about them very clearly:
return number * factorial(--number);
/* A */ /* B */
At spot A we take the value of the variable number.
At spot B we modify the value of the variable number.
But the question is, at spot A, do we get the "old" or the "new" value of number?
Do we get it before or after spot B has modified it?
And the answer, as I already said, is: we don't know. There is no rule in C to tell us.
Again, you might have thought there was a rule about left-to-right evaluation, but there isn't. Because there's no rule that says how an expression like this should be parsed, a compiler can do anything it wants. It can parse it the "right" way, or the "wrong" way, or it can do something even more bizarre and unexpected. (And, really, there's no "right" or "wrong" way to parse an undefined expression like this in the first place.)
The solution to this problem is: Don't do that!
Don't write expressions where one variable (like number) is both used and modified.
In this case, as you've already discovered, there's a simple fix:
return number * factorial(number - 1);
Now, we're not actually trying to modify the value of the variable number (as the expression --number did), we're just subtracting 1 from it before passing the smaller value off to the recursive call.
So now, we're not breaking the rule, we're not using and modifying number in the same expression.
We're just using its value twice, and that's fine.
For more (much more!) on the subject of undefined behavior in expressions like these, see Why are these constructs using pre and post-increment undefined behavior?
How to find the factorial of a number;
function factorial(n) {
if(n == 0 || n == 1 ) {
return 1;
}else {
return n * factorial(n-1);
}
//return newnum;
}
console.log(factorial(3))

Count length and number of words in string

I am a beginner in C. I am trying to print out the length and the number of words in a string inputted by user. I have trouble dealing with the counting of words. I attempt to scan the number of the space character , then add 1 to the result. It is guaranteed that each word is only separated by one space.
I executed the code, and inputted
I go to school by bus.
The second output was not as I expected
22
24
22 is correct since it is indeed the length of the string, but I do not understand why it prints 24 instead of 6 (result of 5 spaces plus 1).
The code is as follows
#include<stdio.h>
#include<string.h>
int main(){
char in[256];
int cl=0,cw,i;
scanf("%[^\n]",&in);
cw=strlen(in);
for(i=0;i<=cw;i++){
if(in[i]=' '){
cl=cl+1;
}
}
printf("%d\n",cw);
printf("%d\n",cl+1);
return 0;
}
What went wrong, and how can I get a correct output?
if(in[i]=' '){
will always be true, you need to change it to
if(in[i]==' '){
2 mistakes I see in your code.
if(in[i]=' ') should be if(in[i]==' ')
== Checks if the values of two operands are equal or not. If yes, then the condition becomes true.
= Simple assignment operator. Assigns values from right side operands to left side operand.
i<=cw should be i<cw
indexing starts with 0 in C.
As Pras said, on ifs you normally use ==, because you are comparing and it returns true or false
If you just use = it attributes (insert) a value on the right to the left.
You should use == instead of = in the if statement that detects the space.
The assignment operator, = gives is always true if the number is asssigned to a nonzero value.
The equivalence operator, == is what actually compares whether two numbers have the same value.
It may be surprising that the assignment operator can actually test whether or not a number is zero(at least on x860. This is because jz, one of the testing instructions, checks something called a flag register (a special memory location) that contains information about the arithmetic operation most recently executed. == does a cmp, which subtracts both numbers from each other to see if it is 0. Jz stands for "jump if zero", so two equal numbers result to the "jump" to the instructions in the if statement. When = is used, the compiler uses jz instead (in order to comply with the c idea that nonzero number in if is true), which results in the behavior described above.

C equivalent operator creating confusion

Program 1:
#include<stdio.h>
void main()
{
int i=55;
printf("%d %d %d %d\n",i==55,i=40,i==40,i>=10);
}
Program 2:
#include<stdio.h>
void main(){
int i = 55;
if(i == 55) {
printf("hi");
}
}
First program give output 0 40 0 1 here in the printf i == 55 and output is 0 and in the second program too i ==55 and output is hi. why
In the first example, the operators are evaluated in reverse order because they are pushed like this on the stack. The evaluation order is implementation specific and not defined by the C standard. So the squence is like this:
i=55 initial assignment
i>=10 == true 1
i==40 == false (It's 55) 0
i=40 assignment 40
i==55 == false (It's 40) 0
The second example should be obvious.
There's no guarantee about the order in which arguments to a function are evaluated. There's also no sequence point between evaluating the different arguments to the function.
That means your first call gives undefined behavior, because it both uses the existing value of i and writes a new value to i without a sequence point between the two.
In a typical case, however, each argument to a function will be evaluated as a separate expression, with no interleaving between them. In other words, the compiler will impose some order to the evaluation, even though the standard doesn't require it to do so.
In the specific case of a variadic function, the arguments are typically pushed onto the stack from right to left, so the first argument (the format string) will be at the top of the stack. This makes it easy for printf to find the format string, and then (based on that) retrieve the rest of the arguments from further down the stack.
If (as is fairly typical) the arguments are evaluated immediately prior to being pushed on the stack, this will lead to the arguments being evaluated from right to left as well.
Functions with a fixed number of arguments aren't evaluated from right to left nearly as often, so if (for example) you wrote a small wrapper taking a fixed number of arguments, that then passed those through to printf, there's a greater chance that i would have the value 55 when the first argument to printf is evaluated, so that would produce a 1 instead of a 0.
Note, however, that neither result is guaranteed, nor is any meaningful result guaranteed--since you have undefined behavior, anything is allowed to happen.
The arguments of printf are evaluated from right to left here (this is unspecified behavior, but the behaviour you noticed shows that at least the first argument is evaluated after the second). In your argument list there ist i=40, which sets the value to 40. Therefore the first printed argument is false (0).
The function printf evaluates the expressions in implementation specific manner, in this case from right to left. Hence the output:
i==55(0),i=40(Assignment),i==40(0),i>=10(1)
The reason is that the order in which the arguments to the printf function (actually any function) are evaluated, before being passed to the function, is not defined by the C standard.
The problem is not with your understanding of the == operator.
Edit: Although many authors are pointing out that printf typically evaluates its arguments from right-to-left (which I wasn't aware of), I would say it's probably a bad idea to write code that depends on this, as the language does not guarantee it, and it makes the code much less readable. Nevertheless is is a good factoid to know in case you come across it in the wild.
In the first program: The order of evaluation of the printf() arguments is implimentation defined. So this program doesn't give the same result on different implimentation of printf() So there is no guarantee about what the program will result.
It could output 0 40 0 1 as it could output 1 40 1 1 if the order of evaluation is reversed.

C Array change causing variable modification

I am trying to modify a value in an array using the C programming language and I seem to be hitting a blank wall with this seemingly easy operation. Please see code snippet below:
while(1) {
printf("Current prime candidate is %i\n",nextPrimeCandidate);
int innerSieve;//=2;
int currentPrimeCandidate=0;
for (innerSieve=2;innerSieve<SIEVELIMIT;innerSieve++) {
currentPrimeCandidate = nextPrimeCandidate * innerSieve;
//printf("Inner Sieve is b4 funny place %i,%i\n",innerSieve,currentPrimeCandidate);
//initArray[currentPrimeCandidate]=5;
//VERY UNIQUE LINE
myArray[currentPrimeCandidate] = 0;
//printf("Inner Sieve after funny place is %i,%i \n",innerSieve,currentPrimeCandidate);
}
nextPrimeCandidate=getNextPrimeCandidate(myArray,++nextPrimeCandidate);
if ((nextPrimeCandidate^2) > SIEVELIMIT ) break;
}
The problem is with the line highlighted with the VERY UNIQUE LINE comment. For some reason, when the innerSieve variable reaches 33 and gets to that line, it sets the contents of the innerSieve variable to the value of that line ( which currently is 0) and basically forces the loop into an infinite loop( the SIEVELIMIT variable is set at 50). It seems that there is some funny stuff going on in the registers when I checked using the Eclipse Debug facility but I am not too sure what I should be looking for.
If you need the whole code listing, this can be provided.( with a particular variable which is not yet initialised in the code being initialised at the precise point that the innerSieve variable hits 32)
Any help will be greatly appreciated.
Guessing that currentPrimeCandidate is greater than the maximum index of myArray, and you're overwriting innerSieve (which likely follows myArray on the stack).
#ruslik hit on it in the comment. The problem is this line:
if ((nextPrimeCandidate^2) > SIEVELIMIT ) break;
In C, the ^ operator is not the power operator, it is the bitwise xor operator. You're iterating far too many times than you intend, which is resulting in an array-index-out-of-bounds error, so you're overwriting random memory and getting strange results.
There is no power operator in C (though there is the pow function). Since you're just squaring a number, the simplest fix is to multiply the number by itself:
if ((nextPrimeCandidate * nextPrimeCandidate) > SIEVELIMIT ) break;

Resources