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.
Related
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))
for (i = 0; isspace(s[i]); i++) { ... }
The above for loop is the part of the program for converting a string to an integer in K&R on page 61.
There's no condition check in that for loop. How does it work?
The loop terminates whenever the condition expression evaluates to 0. If for instance you see an expression like i < 3, you can think of it as (i < 3) != 0. So in this case, it's isspace(s[i]) != 0 meaning it terminates at the first character that is not a space.
isspace(s[i]) is the condition, since it returns a zero value for 'false' (i.e. the provided character is not a space character), and non-zero values for 'true'. In this case, only one space character exists, but in other functions such as isalpha or isalphanum, non-zero values mean different things like 1 means it is an upper-case letter (so it is an alphabetical character), or 2 means it is a lower-case letter) and so on (I may have mixed those numbers up :/).
In otherwords, the for loop is treating this function as returning a boolean value, like most other expressions, meaning it treats zero-values as false, and non-zero as true.
First of all, you're going to get out of bounds, which is gonna give you a segfault. You're just increasing i, but not checking whether it's still in the bounds or not. For example, what if s would be equal to " "? isspace(i[0]) will return a non-zero value (treated as true) and the loop will continue and will try to access the second (non-existent!) value of s. You'd better add another tiny check: for (i = 0; (i<SIZE_OF_S) && isspace(s[i]); i++) { ... }
Let's now talk about the missing condition. No, it's not missing, it's here: isspace(s[i]). This function checks whether s[i] is considered space or not. It returns a non-zero value if yes, and 0 otherwise (docs). So, it is the missing condition, just in a slightly different form (maybe you're used to different comparisons, but there exist a lot more ways.
Yes If the for loop have without condition checking , the for loop will exit whenever the condition part will be zero
For example
`
int i ;
for (i=0; 7-i; i++)
printf("hello world \n");
getch();
return 0;
}`
See the above program the 'i' minus the seven each time . and the loop will exit whenever the value of condition part will be zero (ie 7-7) .
Recently I have some across this solution on codeforces site. I couldn't understand the condition in the if statement and also the condition of the ternary operator in this question can someone please help me with this ?
#include<stdio.h>
int main(void)
{
int a[1000]={0},ans,k;
while((k=getchar())!='\n'){
if(!a[k]){
ans++;
a[k]=1;
}
}
puts(ans&1 ? "IGNORE HIM!":"CHAT WITH HER!");
return 0;
}
It's a bizarre piece of code, I'm not sure entirely why it does what it does but it's easy enough to understand from a technical viewpoint (i.e., what it does).
The while loop gets a series of characters from standard input and, for each unique one, adds one to the ans variable. The expression !a[k] will be true if a[k] is zero (they're all initialised to this state).
When that condition is true, ans is incremented and a[k] is set to 1, meaning any more characters of that value will not affect the outcome (the condition won't ever be true again).
In terms of the if statement, the expression ans&1 will be true if ans is odd (has its lower-order bit set).
So it appears it tells you to ignore people who have an odd number of unique characters in their names and talk to the others. Of course, the whole thing falls apart since you don't actually initialise ans, meaning it can be an arbitrary value (not necessarily zero) and that this program is therefore pretty much able to tell you whatever it wants.
Once you've fixed that little issue, I'll be happy to chat further - paxdiablo has eight unique characters. I should warn you in advance though, I'm not a "HER" :-)
int a[1000] = {0};
This is a way to fill a[1000] with 0s.
If an array is partially initialized, elements that are not initialized receive the value 0 of the appropriate type (https://stackoverflow.com/a/2589751/3235496).
if (!a[k])
checks if k is an "already seen character", thus skipping further increments of ans.
x & 1
Finds if x is even or odd (checking the last bit). You can take a look at What is the fastest way to find if a number is even or odd? for further details.
So
puts(ans&1 ? "IGNORE HIM!" : "CHAT WITH HER!");
prints IGNORE HIM when ans is odd.
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.
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;