Passing bash parameters to c++ - c++

I tried passing two parameters from bash to c++ program to be used but cant seem to get it to work exactly right. I would use the command ./bash "Turtle" "Cat" in linux command line.
#!/bin/bash
./main.out $1 $2
But the C++ file would only read ./main.out from argv. The cout would just print cut off versions of ./main.out such as ./main.out then /main.out and then main.out. Am I incorrectly using the parameters in the placement of the bash file?
int main(int argc, char *argv[]) {
cout << argv+0 << endl;
cout << argv+1 << endl;
cout << argv+2 << endl;
return 0;
}

This is because you are not printing the arguments as strings, your printing their memory locations. In clang++-9 (what I tested it in) this is what happens when a pointer is passed to std::cout, in many compilers (MSVC, correct me if im wrong) this will simply print nothing.
What you need to do is reference it as an array index and print that
int main(int argc, char **argv) {
cout << argv[0] << endl;
cout << argv[1] << endl;
cout << argv[2] << endl;
return 0;
}
The above code works fine for me (passing arguments manually when executing) when compiled with clang++-9. If you are going to use this code you should also check that there are at least 3 arguments (value of argc) otherwise you may point at invalid memory when indexing argv
Also try and avoid std::endl and use "\n" instead, std::endl needlessly flushes the buffer and is not required 99% of the time

Your bash file is fine. The problem is in your C++. Try something like this:
#include <iostream>
int main(int argc, char **argv) {
std::cout << argv[1] << "\n";
std::cout << argv[2] << "\n";
}
[warning: this doesn't check for errors, so if you don't pass any parameters, it'll misbehave badly.]

char *argv[] is a pointer of pointers (same as char **argv), you need
cout << argv[1] << endl;

Related

Command line arguments not passing through correctly, argc always returning 1 and argc returning nullpointer on visual studio c++

I was recently working on a project for a class and was having a lot of problems with passing in command line arguments. I decided to test out with a really simple code I found online from geeksforgeeks to see if I could get any sort of command line stuff to work and it still is not working. It will not print any argv values and when I debug it, it says that argc is 1 despite me putting in 4 command line arguments. I have been trying to find answers to this online for hours and have no idea what is going on especially when using this really simple code. I attached the code I was testing below. It only prints out "You have entered 1 arguments:" I am relatively new to coding but very confused.
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
cout << "You have entered " << argc
<< " arguments:" << "\n";
for (int i = 0; i < argc; ++i)
cout << argv[i] << "\n";
return 0;
}

C++ arguments comparison

Hello I am trying to read some arguments and process them but when i try to read arguments via if else ladder a problem occurs
int main (int argc, char *argv[])
{
cout << argv[1] << endl;
if (argv[1] == "process")
cout << "yes" << endl;
else
cout << "no" << endl;
}
This code outputs:
process
no
Do you know why the output is no instead of yes?
By the way I tried to convert either one of them to a string and compared it with another surprisingly it worked, even though I couldn't figure out why.
argv[1] is a pointer, actually a char * (see the definition char *argv[]), and in your code "process" (which is a const char []) also decays to a const char *, so you are basically comparing two char *.
Since char * are simply pointers, then you are comparing addresses, not "string", and obviously argv[1] and "process" are not stored at the same address.
If you convert one of the two to std::string, then you are comparing a std::string and char * (or const char *), and std::string has an overloaded operator== for char * so it works.
You could compare "C strings" (aka char arrays) using strcmp or strncmp.
argv[1] == "process" compares pointers. Use strcmpto compare the strings behind the pointers:
#include <string.h>
int main (int argc, char *argv[])
{
cout << argv[1] << endl;
if (strcmp(argv[1],"process")==0)
cout << "yes" << endl;
else
cout << "no" << endl;
}

Cast element of character array to integer, and print using cout

I have something in my opinion unexpected happening here.
int main(int argc, char* argv[]) {
cout << "argv[1] : " << argv[1] << endl;
cout << "(int)argv[1] : " << (int)argv[1] << endl;
}
When I call this:
$ ./a.out 1
The output is:
argv[1] : 1
(int)argv[1] : -1074470344
I would expect
argv[1] : 1
(int)argv[1] : 49
Since the ASCII code for '1' is 49.
What is happening here?
Remember that the type of argv is char* argv[], so argv[1] is not a single char, but a C-style string.
To print the first character, use argv[1][0].
std::cout << "(int)argv[1][0] : " << (int)argv[1][0] << std::endl;
argv[1] is not a char, it's a char *.
(int)argv[1][0] may be what you want, if you guarantee the argument will be only one character.
cout << "(int)argv[1][0] : " << (int)argv[1][0] << endl;
and you will get:
argv[1] : 1
(int)argv[1][0] : 49
NOTICE
If your argument is a string like "11", you will get a strange result such as:
argv[1] : 11
(int)argv[1][0] : 49
cout << "(int)argv[1] : " << (int)argv[1] << endl;
You are trying to cast argv[1] which is a char pointer, i.e. "C string". It could also contain "11", not just '1'.
You would need to "cast" the first letter, but I think it is not a good idea either way.
Furthermore, you have not checked against the argc whether you actually supplied the argument on the command line. That is another mistake unless you can make sure somehow it is never "misused".
Yet another mistake is not returning an integer, e.g. zero, at the end of the function since it should, otherwise you will get a warning from your compiler.
You could write this:
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
if (argc == 1)
return 1;
cout << "argv[1] : " << argv[1] << endl;
cout << "(int)argv[1][0] : " << (int)argv[1][0] << endl;
^^^ ^^^
return 0;
}
That being said, you probably want to use static_cast for this in a C++ program rather than low-level C-type cast.

Why does my program not react to any arguments?

I have a simple test program in C++ that prints out attributes of a circle
#include <iostream>
#include <stdlib.h>
#include "circle.h" // contains the Circle class
using namespace std;
void print_circle_attributes(float r) {
Circle* c = new Circle(r);
cout << "radius: " << c->get_radius() << endl;
cout << "diameter: " << c->get_diameter() << endl;
cout << "area: " << c->get_area() << endl;
cout << "circumference: " << c->get_circumference() << endl;
cout << endl;
delete c;
}
int main(int argc, const char* argv[]) {
float input = atof(argv[0]);
print_circle_attributes(input);
return 0;
}
when I run my program with the parameter 2.4 it outputs:
radius: 0.0
diameter: 0.0
area: 0.0
circumference: 0.0
I've previously tested the program without the parameter, but simply using static values, and it ran just fine; so I know there's nothing wrong with the class I made...
So what did I do wrong here?
argv[0] is the program name. You want argv[1] for the first argument.
Also, check that argc is at least two before trying to access it. You might also consider std::stoi, std::istringstream or strtod rather than atoi for conversion, since they can detect bogus input.
Finally, why are using new when an automatic variable will suffice? You should get out of that habit straight away, or spend the rest of eternity debugging memory leaks.
argv[0] is the name of the executable being invoked.
Your first command line parameter will be in argv[1].
To make sure that your program does not silently fail again, you should check how many parameters you actually have and if the atof returns a value, and show a message to the user explaining the issue accordingly.

problem with reading program arguments in Visual Studio C++

I'm running C++ program in VS2005, and I've set only one argument in project properties-> debug-> command line args, and it's named profile1.dll for example.
here's a code snippet
cout<<"number of arguments:" << argc<<endl;
for (int i=0; i<argc; i++)
cout << "argument " << i << ": " << argv[i] << endl;
In the output I get
number of arguments:2
argument 0: c
argument 1: p
don't know why it doesn't print the name of the argument?
Does the name of your exe start with C? If you expect a string and you only get one character, it's usually because you've discovered that the Western alphabet in UTF-16 Unicode effectively puts a 0 between alternating ANSI chars. Are you compiling for Unicode ?
argv[0] is the name of your program. argv[1] is the first parameter. It sounds like you have declared the relevant parameter in main() as char* argv rather than char *argv[] or char **argv.
Leave TCHAR be, it's fine.
If you compile with unicode, use wcout for output:
int _tmain(int argc, _TCHAR* argv[])
{
for (int i=0; i<argc; i++)
wcout << "argument " << i << ": " << argv[i] << endl;
return 0;
}
Otherwise compile without unicode and your code will just work as-is (and will not work with unicode parameters :o)
You can find setting in "Project Properties/General/Character Set"
Can you put the prototype of your main function? What you are doing is apparently fine.
Make sure your main's function prototype is something similar to:
int main(int argc, char **argv)
Hope it helps.