Parsing arguments from main C++ [duplicate] - c++

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)

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 the if statement is ignoring the command line argument? [duplicate]

This question already has answers here:
What is the proper function for comparing two C-style strings?
(2 answers)
Compare equality of char[] in C
(5 answers)
Closed 2 years ago.
I'm trying to make a simple program that takes one argument. I use as main:
int main(int argc, char* argv[]) {
if (argv[1] == "string") {
cout<<"STRING AS ARG!!"<<endl;
}
return 0;
}
But when I run it with program.exe string nothing happens. What is wrong with the piece of code?
The problem is that both operands are C strings and the comparison does a raw pointer comparison. You need to make at least one operand a std::string or a std::string_view.
std::string_view is the best option because it avoids the overhead of the std::string, but you need C++17:
#include <string_view>
using namespace std::literals;
if (argv[1] == "string"sv)
The std::string versions. If you have C++14 you can use the literal:
#include <string>
using namespace std::literals;
if (argv[1] == "string"s)
Or if you are pre C++14:
#include <string>
if (argv[1] == std::string("string"))
argv[1] is a pointer (char *). You can not compare it to "string" using ==, it'll always return false. You should use strcmp:
if (strcmp(argv[1], "string") == 0)

How to solve error "invalid conversion of char to char*" when using strupr and strlwr?

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int i;
char s[100];
cin >> s;
for(i=0;i<strlen(s);i++)
{
if(islower(s[i])==1)
{
s[i]=strupr(s[i]);
cout << s[i];
}
else
{
s[i]=strlwr(s[i]);
cout << s[i];
}
}
return 0;
}
These two lines i.e. s[i]=strupr(s[i]) and s[i]=strlwr(s[i]) shows this error :
invalid conversion from char to char*.
How can I solve it? Thank you.
You should use these two instead:
s[i] = std::toupper(s[i]);
s[i] = std::tolower(s[i]);
Remember to include <cctype>. Here is a link to some documentation of std::toupper and std::tolower.
The problem is that strupr and strlwr work on entire strings, not single characters. Moreover, they operate in-place and they are non standard.
Side note:
You could consider using a std::string s instead of char s[100], this removes the current overflow opportunity in cin >> s;.
Update:
It is possible to use std::transform like so:
std::transform(std::begin(s), std::end(s), std::begin(s), [] (char c) { return std::islower(c) ? std::toupper(c) : std::tolower(c); });
One benefit of using std::begin(s) and std::end(s) is that it works for both std::string, std::vector and even char[100].
strupr and strlwr expect a char* and not a char as their parameter.
You would need to pass the whole s array instead of s[i]
Alternatively use the std::toupper and std::tolower which would allow you to do each character in turn.
You can also get rid of the raw loop by using std::transform and a predicate or lamda
char InvertCase(char c)
{
return islower(c) ? std::toupper(c) : std::tolower(c);
}
std::transform(s.begin(), s.end(), back_inserter(result), InvertCase);
sdtrupr and strlwr take char * as an argument. To convert a single character use tolower and toupper
strupr() modifies in place its string (that is, char[]) argument replacing all lowercase letters with uppercase. I think that you are confusing strupr() with toupper().
Note that by using strupr() or toupper() you are making an implicit assumption that each char represents a character; this is not true for multi-byte encodings such as UTF-8.

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.