Comparison in string literal results in inspecified behavior - C++ - c++

I'm using eclipse.
I declared #define OUTPUT_FLAG "-o"
and then, I have the main : int main(int argc, char **argv)
after that I write:
for (int i = 1; i < argc; i+=2)
{
if(argv[i]==INPUT_FLAG)
{
cout<<"input flag\n";
input_file=argv[i+1];
}
}
and there I get the error on the subject. Can you help me here?
Thank you

You cannot compare strings with == in C++. You either have to use strcmp or convert them to std::strings and then use the == operator. That is, either:
if (!strcmp(argv[i], INPUT_FLAG))
or
if (std::string(argv[i]) == INPUT_FLAG)

You can't compare C strings (char *) using the == operator, as that operator only checks for pointer equality (rather than dereferencing the pointer and comparing each character one by one). Use strcmp(), or convert the string in argv[] to a C++ string type first.

Related

pointer comparision with int type in c++ [duplicate]

This question already has answers here:
Comparing command parameter with argv[] is not working
(4 answers)
Closed 1 year ago.
I executed the below program as: ./aout w.
#include<iostream>
using namespace std;
int main(int argc, char** argv)
{
if (argv[1] == "w")
{
cout << "this was worked";
}
else
{
cout << "this did not worked";
}
}
OUTPUT: this did not worked.
I tried executing: if(&argv[1] == "w")
if(argv[1]=='w')
The line
if (argv[1] == "w")
is equivalent to
char const* p1 = argv[1];
char const* p2 = "w";
if ( p1 == p2 )
i.e. you are comparing two pointers, not the strings that the pointers point to.
You can use std::strcmp. However, since you are using C++, you might as well use std::string.
if (std::string(argv[1]) == "w")
If you are able to use C++17, you may use std::string_view too.
if (std::string_view(argv[1]) == "w")
If you compare arrays and pointers using the equality operator, then you are comparing whether they are the same array or point to the same object. You aren't comparing the content of the arrays or pointed elements. Since argv[1] points to a different array than the string literal, they compare unequal regardless of their content.
tried executing: if(&argv[1] == "w")
Now, you're comparing char** to a const char* (after array decay). Comparing pointers of unrelated types doesn't make much sense.
if(argv[1]=='w').
Now, you're comparing char* to char. Comparing a pointer to a char doesn't make much sense.
To compare the content of two strings, A good solution is to use a string view as either or both of the operands. It's a small change:
using namespace std::literals;
if (argv[1] == "w"sv)

Why aren't my commandline arguments being read?

I am calling this in my program:
std::string gameDirectory = "";
for (int i = 1; i < argc; i++)
{
if (argv[i] == "-game")
gameDirectory = argv[i + 1];
}
if (gameDirectory == "")
exit(0);
With the commandline argument
-game demo
and it refuses to set the gameDirectory. Any ideas?
argv[i] is of type const char*, and direct comparison of pointers return true only if they point to the same location. Program arguments will never point to the same location as existing constant strings, so the if is never visited.
You either need to make either string a std::string (which has == overloads for comparing with char pointers), or use strcmp to compare the arguments instead.
if (strcmp(argv[i], "-game") == 0)
Turn on your compilation warnings!!!
main.cpp: In function 'int main(int, char**)':
main.cpp:8:24: warning: comparison with string literal results in unspecified behaviour [-Waddress]
if (argv[i] == "-game")
^
This warning tells you everything you need to know (live).
Use strcmp to compare C-strings.

How to call a function of this type

/* Write a function that returns the length of a string(char *), excluding the final NULL
character.It should not use any standard - library functions.You may use arithmetic and
dereference operators, but not the indexing operator ([]) */
#include "stdafx.h"
#include<iostream>
using namespace std;
int stringLength(const char * str) {
int length = 0;
while (*(str + length) != '\0') {
++length;
cout << length;
return length;
}
int _tmain(int argc, _TCHAR* argv[]){
stringLength({ 'a', 'b', 'c', '\0' });
return 0;
}
Somehow I think I am not calling my function properly in the main function, but I am not sure how else I should do it. What is the proper way of calling a function of this type? (Sorry if this is a stupid question: I am new to C++)
Like: int l = stringLength("abc");
C constant strings are automatically zero terminated, so you don't need to specify the extra zero character.
Pass a string. For instance
int len = stringLength("abc");
FWIW, it would be idiomatic to use size_t for the return type of this function. When you try to work with other code you'll meet resistance to having used int rather than size_t.
The code in the question is also rather poorly formatted and does not compile. You omitted a closing brace. It pays to get this sort of detail just right.

Issue with main arguments handling

I can't compare main() arguments with const char* strings.
Simple code for explaining:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
if(argc>1)
{
for (i=1;i<argc;++i)
{
printf("arg[%d] is %s\n",i,argv[i]);
if(argv[i]=="hello")
printf(" arg[%d]==\"hello\"\n",i);
else
printf(" arg[%d]!=\"hello\"\n",i);
}
}
return 0;
}
Simple compile g++ test.cpp. When I try execute it, I see next thing:
>./a.out hello my friend
arg[1] is hello
arg[1]!="hello"
arg[2] is my
arg[2]!="hello"
arg[3] is friend
arg[3]!="hello"
Whats wrong with my code?
Strings can't be compared with ==, use strcmp:
if (strcmp(argv[i], "hello") == 0)
You have to #include <string.h>
Whenever you use argv[i] == "hello", the operator "==" donot take string as its operand so in actual the compiler compares the pointer to argv[i] with the pointer to constant string "Hello" which is always false and hence the result you are getting is correct, to compare string literals use srtcmp function.
int strcmp(const char *s1, const char *s2);
which compares the two strings s1 and s2. It returns an integer less than, equal to, or greater than zero, if s1 is found, respectively, to be less than, to match, or be greater than s2.
In this statement
if(argv[i]=="hello")
you compare pointers because the string literal is implicitly converted to const char * (or char * in C) that points to its first character. As the two pointers have different values the expression is always false. You have to use standard C function strcmp instead. For example
if( std::strcmp( argv[i], "hello" ) == 0 )
To use this function you should include header <cstring>(in C++) or <string.h> (in C).

Parsing arguments from main C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C String — Using Equality Operator == for comparing two strings for equality
Basic question here. I'm compiling this program in g++ and running it with a single -r argument, (./a.out -r) however it does not output the specified cout statement below. Is there anything wrong with this code?
#include <string>
using namespace std;
int main(int argc, char* argv[]) {
if (argv[1] == "-r" ) {
cout << "First arg is -r" << endl;
}
return 0;
}
You cannot compare string literals using ==, because what that does is compare pointers (i.e., memory addresses, which in this case are always going to be different).
Use strcmp or compare std::string objects instead:
if (strcmp(argv[1], "-r") == 0) { ... }
or
if (std::string(argv[1]) == "-r") { ... }
You can't compare string literals with ==. Use strcmp.
(Also, don't forget to check that argc is at least 2).
One mistake in your code is you are comparing the address of the char array instead of comparing the values in the array. As people have said you can do it the C way using strcmp (although it's safer to use strncmp to avoid buffer overruns).
However, it's easier to use std::string in C++.
I would copy the args into a vector of strings.
#include <vector>
#include <string>
int main(int argc, char* argv[])
{
vector<string> args(argv, argv+argc);
...
Usually you would do something along these lines:
while (--argc && **++argv=='-')
{
char *p;
p=*argv+1;
switch(tolower(*p))
{
case 'r':
break;
}
}
basically, while there are some args left, check that there is a '-' char, then switch on the next char to see the modifier ('r', or 'a' etc)