Comparing String if( "bonaparte"=="bonaparte" ) this gives true result? - c

Note: I know I can do this stuff by using strcmp() but I am just trying the equal to == operator.
Code 1:
#include<stdio.h>
int main()
{
char s1[]="bonaparte",s2[]="bonaparte";
if(s1==s2)
{
printf("True");
}
else
{
printf("Flase");
}
}
Output:
False
Code 2:
#include<stdio.h>
int main()
{
char s[]="bonaparte";
if(s=="bonaparte")
{
printf("True");
}
else
{
printf("Flase");
}
}
Output:
False
Code 3:
#include<stdio.h>
int main()
{
if("bonaparte"=="bonaparte")
{
printf("True");
}
else
{
printf("Flase");
}
}
Output:
True
So, in #1, we compare the base addresses of s1 and s2 and obviously they are going to different, so the output is "False".
In #2, we are comparing the base address of s and the base address of the constant string "bonaparte" and obviously it is again going to be different, so the output is "False".
However, in #3, we are comparing base addresses of one constant string "bonaparte" and another constant string "bonaparte". I think that the string names are same but they will get different locations in memory so, when we are trying to compare their base addresses, they should be different. But output is contradicting to above (what I think).
So what is exactly happening in the 3rd case?

When compiling your third code sample, the compiler is applying what is often called "string pooling" – that is, the compiler spots that two (or more) string literals are the same and, as such constants cannot be changed at runtime, optimizes the code by generating only one instance of the data, so the two literals end up with the same address.
Most compilers do this by default, but you may be able to disable it. For example, in Visual Studio with the MSVC compiler, you can set the /GF- option to disable it. With this set, your code above gives "Flase" (sic) as the output (Reference).

Related

Searching for all integers that occure twice in a vector

I got the task in university to realize an input of a maximum of 10 integers, which shall be stored in a one dimensional vector. Afterwards, every integer of the vector needs to be displayed on the display (via printf).
However, I don't know how to check the vector for each number. I thought something along the lines of letting the pointer of the vector run from 0 to 9 and comparing the value of each element with all elements again, but I am sure there is a much smarter way. I don't in any case know how to code this idea since I am new to C.
Here is what I have tried:
#include <stdio.h>
int main(void)
{
int vector[10];
int a;
int b;
int c;
a = 0;
b = 0;
c = 0;
printf("Please input 10 integers.\n\n");
while (a <= 10);
{
for (scanf_s("%lf", &vektor[a]) == 0)
{
printf("This is not an integer. Please try again.\n");
fflush(stdin);
}
a++;
}
for (b <= 10);
{
if (vector[b] != vector[c]);
{
printf("&d", vector[b]);
c++;
}
b++;
}
return 0;
}
Your code has several problems, some syntactic and some semantic. Your compiler will help with many of the former kind, such as
misspelling of variable name vector in one place (though perhaps this was a missed after-the-fact edit), and
incorrect syntax for a for loop
Some compilers will notice that your scanf format is mismatched with the corresponding argument. Also, you might even get a warning that clues you in to the semicolons that are erroneously placed between your loop headers and their intended bodies. I don't know any compiler that would warn you that bad input will cause your input loop to spin indefinitely, however.
But I guess the most significant issue is that the details of your approach to printing only non-duplicate elements simply will not serve. For this purpose, I recommend figuring out how to describe in words how the computer (or a person) should solve the problem before trying to write C code to implement it. These are really two different exercises, especially for someone whose familiarity with C is limited. You can reason about the prose description without being bogged down and distracted by C syntax.
For example, here are some words that might suit:
Consider each element, E, of the array in turn, from first to last.
Check all the elements preceding E in the array for one that contains the same value.
If none of the elements before E contains the same value as E then E contains the first appearance of its value, so print it. Otherwise, E's value was already printed when some previous element was processed, so do not print it again.
Consider the next E, if any (go back to step 1).

Please explain the output to this code: [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
#include<stdio.h>
void main()
{
if(0xA)
if(052)
if('\xeb')
if('\012') //what do the above 3 statements mean?
printf("Hello World!")
else;
else;
else;
else;
}
Output:
Hello World!
so here, what is the meaning of 052, \xeb and \012?
And what is the significance of the multiple else statements?
From the C Standard (6.8.4.1 The if statement)
2 In both forms, the first substatement is executed if the
expression compares unequal to 0. In the else form, the second
substatement is executed if the expression compares equal to 0. If the
first substatement is reached via a label, the second substatement is
not executed.
So as each expression in the if statements
if(0xA)
if(052)
if('\xeb')
if('\012')
are unequal to 0 then the enclosed call of the function printf (provided that a semicolon is present)
printf("Hello World!");
is executed.
So the if statements do not make much sense.
0xA is a hexadecimal integer constant equal to decimal 10
052 is octal integer constant equal to decimal 42
'\xeb' is a character constant specified as a hexadecimal escape sequence
'\012' is a character constant specified as an octal escape sequence
Take into account that according to the C Standard the function main without parameters shall be declared like
int main( void )
Thus as each expression of the if statements is not equal to 0 then the program is in fact equivalent to the following program
#include<stdio.h>
int main( void )
{
printf("Hello World!");
}
This is a trick question. Presumably someone thought you could learn something from it. Presumably this person also thinks that a good way to teach a child to ride a bicycle is to flatten the bicycle's tires, and put large boulders in the way, and randomly give the child a rough shove to the side, because it "builds character", and if you can learn to ride a bicycle in spite of those obstacles, you will eventually be a really good bike rider. But I digress.
Anyway, here's an explanation of what's going on in that code.
0xA is a hexadecimal constant. It has the value 0A16, or 10 (base 10).
052 is an octal constant. It has the value 528, or 42 (base 10).
'\xeb' is a hexadecimal character constant. It is a character with the value EB16, or 235 (base 10) (which in ISO-8859-1 or Unicode ends up being an e with two dots over it, ë).
'\012' is an ordinary, octal character constant. It is a character with the value 128, or 10 (base 10) (which in ASCII ends up being a newline character, '\n').
When you say
if( expr )
in C, the expression is considered "true" if it is nonzero, or "false" if it is zero. Needless to say, all four of those constants are nonzero.
The full syntax of an if statement in C is either
if( expr )
statement-or-block
or
if( expr )
statement-or-block
else
statement-or-block
where statement-or-block is either a single statement, or a "block" (sequence) of multiple statements enclodes in braces { }.
A little-used piece of syntax in C is the "empty statement". If you have nothing, followed by a semicolon, that's an empty statement, and it does... nothing.
It is considered mandatory in polite circles to indent your code to portray its structure. So the normal way of presenting this code would be:
#include <stdio.h>
int main()
{
if(0xA)
if(052)
if('\xeb')
if('\012')
printf("Hello World!")
else
;
else
;
else
;
else
;
}
And, again, all four expressions evaluate immediately to "true". So, in English, this code says "If true, then if true, then if true, then if true, then print 'Hello world!', else do nothing, else do nothing, else do nothing, else do nothing."
Phrased that way it sounds pretty stupid, I know. And in fact, it's just as stupid in C as it is in English.
P.S. Besides the bizarre and unnecessary conditionals, another problem with the code as posted, which I have quietly corrected, is that it declared main as void, which is something else that's not done in polite circles, and throws further doubt on the validity of the book this code came from.
The code you posted is equivalent to
#include<stdio.h>
int main( void ) // void main() is not a standard signature
{
if(0xA)
{
if(052)
{
if('\xeb')
{
if('\012')
{
printf("Hello World!")
}
else
{
}
}
else
{
}
}
else
{
}
}
else
{
}
}
Curly braces can be omitted if there is only a single statement within them:
if ( a )
{
do_something();
}
can be written as
if ( a )
do_something();
although I and others recommend against doing this except in specific cases.
An if statement itself counts as a single statement, so it's possible to write
if ( a )
{
if ( b )
do_something();
}
as
if ( a )
if ( b )
do_something();
And, of course, the compiler doesn't care about indentation, so
if ( a )
if ( b )
do_something();
means the same thing - however, as you've discovered, code written this way is a little hard to understand.
The test condition of an if, while, or for may be any scalar type (integer, floating-point, or pointer value). C didn't originally have a distinct Boolean type, so the rule is any non-zero value in a Boolean context evaluates to "true", while zero evaluates to "false".
Each of 0xA, 052, '\xeb', and '\012' is a scalar expression with a non-zero value (0xA and 052 are integer literals in hexadecimal and octal format, respectively, while '\xeb' and '\012' are escape sequences representing character values in hex and octal format), so the bodies of all the if statements are executed.
You have four nested if statements, and only the innermost one is doing anything interesting. The else clauses are empty and can be omitted entirely:
#include<stdio.h>
int main( void )
{
if(0xA)
{
if(052)
{
if('\xeb')
{
if('\012')
{
printf("Hello World!")
}
}
}
}
And, as I said above, the curly braces may be omitted as well:
#include<stdio.h>
int main( void )
{
if(0xA)
if(052)
if('\xeb')
if('\012')
printf("Hello World!")
}
All of which reduces to
int main( void )
{
printf("Hello World!")
}
A reasonably smart compiler won't bother generating the machine code for the if statements at all, and should generate machine code as though the program had been written as above.

Why this is not working? Strings in C. If always true. WHY?

Please help me.
I don't know why this program is not working.
Sorry, but I needed to post whole code so it can be understanded clearly.
I tried to put str in txt file and then read it again and it is the same problem.
Also, I tried changing pointers with some other and then sompareing them and also the samo problem.
Arguments of program are:
1) txt file - with something like this - xyxxyyyxyxxyxyyxyxyxyyyyxxxx...
2) number - example - 2 - means that i need to group symbols in pairs
Output should be probaillity of any combination of x and y (xx,yy,xy,yx - for group of 2).
example:
p(xx)=0.4
p(yy)=0.1
p(yx)=0.5
p(xy)=0
BUT!
this is ALWAYS TRUE:
if (str==lista[i])
WHY?
I am struggling with it for hours. :(
I tried what others suggested:
Look at this:
http://i.imgur.com/SL1L8hc.jpg and
http://i.imgur.com/QwZGdgM.jpg
Weirdest one:
http://i.imgur.com/BIeLXOu.gif
WHOLE CODE:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
typedef char * string;
int main(int argc, char *argv[]){
if (argc<3) {
return -1;
}
FILE *ul;
int mode,i,dane,j,razl;
char *str;
int brojac=0;
string lista[1000];
int pomlis[1000];
ul=fopen(argv[1],"r");
fseek(ul,0,SEEK_SET);
if (!ul){
return 1;
}
for (i=0;i<1000;i++){
lista[i]="nist";
pomlis[i]=0;
}
mode=atoi(argv[2]);
str=(char*)malloc(mode+1);
brojac=0;
razl=0;
while (fgets(str,sizeof(char)*mode+1,ul)!=NULL){
dane=0;
// printf("%s ",str); //da bi printao u konzolu
brojac++;
for (i=0;i<=razl;i++){
if (str==lista[i]){
pomlis[i]++;
dane=1;
}
}
if (dane==0){
if (lista[i]=="nist") i--;
lista[i+1]=str;
pomlis[i+1]=1;
razl++;
}
}
for (i=1;i<=razl;i++){
printf("p(%s)=%f\n",lista[i],pomlis[i]/((double)brojac));
}
fclose(ul);
return 0;
}
I tried all suggestions in the comments and nothing works. Does anyone knows the answer?
First of, sizeof(char) is 1 by definition. It doesn't make the code more readable.
The line
fgets(str,sizeof(char)*mode+1,ul);
reads into char *str which is allocated in
str=(char*)malloc(sizeof(char)*mode);
Which should omit the cast, and is too small to hold everything fgets() writes to it (by the +1 '\0').
In addition:
printf("p(%s)=%d\n",lista[i],pomlis[i]/brojac);
pomolis[i] and brojac are both integers, therefore the division will not return a fraction (float/double) but an integer again (most likely zero in your program).
Thank you all, edited, but, can I get answer? Why I am getting minuses on question if no one knows answer?
Well, try replacing the line
if (str==lista[i]){
with
if (!strncmp(str, &lista[i], mode){
and remove the line
fgets(str,sizeof(char)*mode+1,ul);
in the body of the while-loop (you are already calling fgets() in the while condition, don't call it twice)
Your code has many problems. I suggest reading about pointers, memory allocation and how strings work in c. Because of your typedef char * string i suppose you must be coming from a higher language then c. Forget that knowledge, you'll have big problems if you try to apply it here.
I've made it work, but I will not post the working code here, as I'm not interested in doing anyone's homework. I'll try to teach you what your problems are.
Your first problem is here:
for (i=0;i<1000;i++){
lista[i]="nist";
pomlis[i]=0;
}
Assigning "nist" to char * assigns the address of a constant string "nist" to the pointer. As the string is constant, if you later try to change something in it, you will fail.
You should use malloc, which allocates memory you can write to:
for (i=0;i<1000;i++){
lista[i]=(char*) malloc(5);
pomlis[i]=0;
}
Next, as others have explained, using == is quite different then using strncmp. You should use:
if (strcmp(str, lista[i])==0){
pomlis[i]++;
dane=1;
}
The next part makes absolutely no sense:
if (dane==0){
if (lista[i]=="nist") i--;
lista[i+1]=str;
pomlis[i+1]=1;
razl++;
}
First you're comparing to another pointer to constant string (note that "nist" you've initialized to doesn't have to be the same "nist" you have here). I really have no idea what you're trying to accomplish using i here.
I wrote it like this:
if (dane==0){
memcpy(lista[razl],str, sizeof(str));
pomlis[razl]=1;
razl++;
}
Try to understand this.
Finally, your for loops go to the limit i<=razl. As arrays are zero initialized, you should break before i hits razl.
if (str==lista[i])
Now, str and lista[i] are of type char*. That is they are pointers. In which case the == operator tests for equality of the pointer addresses. So, if this == operator evaluates true then the two pointers have the same address.
If you want to compare the value of the string then you must use strcmp().

recursive functions in C: is return always necessary?

this is my first time playing with recursive functions, and this function that I wrote returns the size of a string if it contains only letters in ascending order, and if not it returns -1.
I don't understand why it works for both codes, after I took out the second "return". Is one more wasteful than the other? Would appreciate some insight.
with "return only_ascending_letters(string, index+1);"
#include <stdio.h>
int only_ascending_letters(char string[], int index);
void main() {
char string1[]="Hi my name is pete";
char string2[]="aabcdefg";
printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0));
}
int only_ascending_letters(char string[], int index){
if(!string[index]) return index;
if(((string[index]>='a'&&string[index]<='z')||(string[index]>='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1]))
return only_ascending_letters(string, index+1);
else return -1;
}
with "only_ascending_letters(string, index+1);"
#include <stdio.h>
int only_ascending_letters(char string[], int index);
void main() {
char string1[]="Hi my name is pete";
char string2[]="aabcdefg";
printf("the first string is %d and the second one is %d\n",only_ascending_letters(string1,0),only_ascending_letters(string2,0));
}
int only_ascending_letters(char string[], int index){
if(!string[index]) return index;
if(((string[index]>='a'&&string[index]<='z')||(string[index]>='A'&&string[index]<='Z'))&&((string[index]<=string[index+1])||!string[index+1]))
/*Took out the return*/ only_ascending_letters(string, index+1);
else return -1;
}
Yes, you absolutely need the return. Note that C language rules are a bit lax about this issue, and if you hadn't used the return value, it would be fine without it. However, you use the return value, so you need the return statement.
What you see is probably caused by the implementation detail that function on some architectures return (integral values) by setting a well known register to that value (eax on i386). Therefore, if the bottommost recursive call does return and set this register, and the calls in-between don't stomp on that register, you see that it sort of works. However, you mustn't rely on that.
Note that good compilers will recognize this is a tail-recursive call and compile both variant basically the same way.
First of all, main() returns an int (actually, a type compatible with int).
Second, you should format your code more. Whitespace is your friend, as are line breaks. It was hard to tell whether the code without return was actually correct because most of it ran offscreen.
Third, you should always work with all [reasonable] warnings enabled. Doing so would have caught the missing return condition, as well as the void main().
As for the answer, #jpalecek has done a great job providing it. I would only like to add that undefined behavior is a beast. If you rely on it, a "working" program may stop doing so just because you decided to compile it again, played some music while running it, or the phase of the moon changed.
All I could find in the [99] standard was §6.9.1 clause 12:
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.
You have two exit conditions. You either run off the end of the string, in which case your condtion of ascending characters is met and you return the length of the string, or you find a character that fails your ascending test, in which case you return -1.
Not returning the value from the call to the recursive function may work on some implementations of the compiler but with a different compiler or different optimisation flags, it may well not work so you should keep the return in your code.

switch statement using string in C [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C/C++: switch for non-integers
C/C++ switch case with string
I am passing a string to a function get_band(char *str)
Then I am comparing the passed argument with a specific string
if(strcmp(str, "auto"))
{
//do something
}
My question is - since i have many number of strings to compare, how can i use switch statement instead of if/else, since switch statement supports only integral type.
Short answer: you can't.
Long answer: this question is a duplicate of C/C++ switch case with string.
You could do:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *words[] = {"one", "two", "four"}; // words is an array of pointers to char
void f(char *str);
int main(void) {
f("two");
return 0;
}
void f(char *str) {
int i;
for (i = 0; i < sizeof words/sizeof words[0]; i++) {
if (!strcmp(str, words[i])) {
/* Do something */
}
}
}
No, switch only works for integers.
If you want to optimize, you can use some data structure to determine if the string is any of the known strings. For example:
hash table
trie
some self-balancing binary search tree, like AVL tree or red-black tree
To make use of such a data structure, assign each known string a constant integer (e.g. define or enum); given a string, you can use the data structure to map it to some number of a known string (possibly with some number meaning "unknown"). Then you can use a switch on this number and do whatever you want for each case.
You can find an existing implementation of any of the above, but if you're new to C, it might be beneficial to implement it yourself.
A switch statement branches based on evaluating the following expression.
In your case, strcmp only promises to return less than zero, zero, or greater than zero. Even if you assume that means -1, 0, and 1 (respectively), that would mean you would only have 3 values you could choose from in your switch cases. [And that is not a safe assumption, by the way ...]
Instead, if your strings are taken from a closed set of strings (i.e. can only have one of set of values), you could tokenize the string. There are actually programs to do this for you, i.e. turns strings into tokens. (See flex(1).) This would mean that each string you expected would have some unique value, and you could switch on that value.
If this is too much trouble, just use the method you used in your question, i.e.:
if (strcmp("some string", str) == 0) {
// handle some string
} else if strcmp("some other string", str) == 0) {
// handle alternate case here
...
} else {
// handle error/default case here
}
Consider changing the logic of your program to use enums instead of strings. You can then use an array look up to map the integer enums to the corresponding string for display and logging purposes. The other options including hash etc have been covered.
The switch statement in C / C++ accepts only three case types : integers, characters and enumerated data types (which is effectively another way of saying integer). Characters also reduce to integers when evaluated as ascii codes.
#Nikolai N Fetissov made a good suggestion : switch on a hash of the string :
#define hashOfString1 <integer hash goes here>
#define hashOfString2 <integer hash goes here>
#define hashOfString3 <integer hash goes here>
. . .
switch (hashMyString("MyString")) {
case hashOfString1:
/* do this */
break;
case hashOfString2:
/* do that */
break;
case hashOfString3:
/* do other */
break;
default:
/* default behavior */
break;
}

Resources