Why aren't my commandline arguments being read? - c++

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.

Related

Checking variable arguments for type

I have the below a function I use for string concatenation, it takes in a variable length set of arguments. I want to check to make sure each element is
a char*. I was looking into using dymanic_cast but it cannot be used for char*.
How should I go about casting the arg?:
char* Concatenate(int numStrings, ...)
{
vector<char*> stringVectorArray;
va_list vargList;
if (numStrings > 0 && numStrings < MAX_STRING_BUFFER_SIZE)
{
//Store each of the arguments so we can iterate through them later.
va_start(vargList, numStrings);
for (int currIndex = 0; currIndex < numStrings; currIndex++)
{
char* item = (char*)(va_arg(vargList, char*));
if (item == NULL)
{
//Error: One of the parameters is not char*.
va_end(vargList);
return NULL;
}
else
{
stringVectorArray.push_back(item);
}
}
va_end(vargList);
}
return ConcatenateStrings(stringVectorArray);
}
You simply don't know. There is no well-defined way of knowing what the argument types are for a variable argument list.
You have to trust the caller to get it right: in C, use the (char*) notation, in C++ use reinterpret_cast.
The variadic templates of C++11 introduce type safety into variable argument lists.
"cannot be used for char*"
Don't use char* then, use an object which CAN be used with dynamic cast, like std::string or your own class.

cannot convert 'const char **' to 'const char*'

Good morning everyone! I am trying to create a fork/exec call from a parent program via a passed '-e' parameter (e.g. parent -e child key1=val1 ...). As a result I want to copy all the values after the first two in the argv array into a new array child_argv. Something like:
const char *child_argv[10]; // this is actually a global variable
static const char *sExecute;
int I = 0;
const char *Value = argv[1];
sExecute = Value;
for (i=2; i<argc; i++) {
child_argv[I] = argv[i];
I++;
}
child_argv[I] = NULL; // terminate the last array index with NULL
This way I can call the exec side via something like:
execl(sExecute, child_argv);
However I get the error message "error: cannot convert 'const char**' to 'const char*' for argument '2' to 'execl(const char*, const char*, ...)'". I have even tried to use an intermediate step:
const char *child_argv[10]; // this is actually a global variable
static const char *sExecute;
int I = 0;
const char *Value = argv[1];
sExecute = Value;
for (i=2; i<argc; i++) {
const char *Value = argv[i+1];
child_argv[I] = Value;
I++;
}
child_argv[I] = NULL; // terminate the last array index with NULL
But I can't figure this out. Any help would be greatly appreciated!
UPDATE
As was pointed out, I should be using 'execv' instead of 'execl' in this situation. Still getting errors though...
UPDATE 2
I ended up copying the array without the desired parameters of argv. See the post here to see the result How to copy portions of an array into another array
From here: http://linux.die.net/man/3/exec
I think you mean to call "execv" not "execl". Execl seems to take a variable number of arguments, expecting each const char * to be another argument, while execv takes an array of arguments.
You should be using execv. When you convert to execv, for some reason execv expects a array of non-const pointers instead of const pointers, so you either have to just cast the array to (char**) or copy the strings into (char*) pointers.

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).

Comparison in string literal results in inspecified behavior - 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.

Reversing a char array in C++ causing an error

I am using the following code in order to reverse a char array. My code as well as the error can be found below.
My code:
char * reverseStr(char* s) {
int i=0; //legnth of string
while(s[i]) i++;
char reversed[i];
for(int j=0; j<i; j++) {
reversed[j] = s[i-j - 1]; //look at this later
}
return *(reversed);
}
The error:
Compiling...
Compile error: your program did not compile correctly:
program.c: In function 'char* reverseStr(char*)':
program.c:18: error: invalid conversion from 'char' to 'char*'
--> 17: }
--> 18: return *(reversed);
Thank you in advance!
Your return value and type is wrong.
Furthermore, your declaration of reversed is invalid and would leak memory in any case.
Also, calculating the string length instead of using std::strlen isn’t recommended and the standard library has the std::reverse function to reverse strings.
Well, you are returning a char instead of a char*, so you are only returning the first letter in the reversed string instead of a string. Which causes your error messages, because you try to treat a char as a char*.
Check the error message:
program.c: In function 'int itoa2(int, char*, int)':
program.c:45: error: invalid conversion from 'char' to 'const char*'
It clearly tells you what the error is: invalid cast from const char* to char
In your code i is not const.
char reverseStr(char* s) {
int i=0; // --->> NOT CONST
while(s[i]) i++;
char reversed[i];
for(int j=0; j<i; j++) {
reversed[j] = s[i-j - 1]; //look at this later
}
return *(reversed);
}
char reversed[i]; ---> Variable Length Array in C++?? i is supposed to be known at Compile time.
strcpy receives (char*, const char*) as parameters.However, the return type of your function is char, thus the error appears.
And char reversed[] is allocated on the stack of the function, please don't use it as a return value.