C++ EXC_BAD_ACCESS, argv[] - c++

I've been stuck on this for a while and can't debug this EXC_BAD_ACCESS error. I have run NSZombie and I am pretty sure its a memory issue with argv[1] (or anything more for that matter). I've checked my syntax and libraries so I don't know why it wont store past arg[0].
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
cout << "Enter the initial bankroll" << endl;
int bankroll = atoi(argv[1]); //code faults here
cout << "Enter seed" << endl;
int seed = atoi(argv[2]);
// ...
I left out the rest because the error occurs before anything else.
The code runs in the terminal but fails the automatic grader for my class.
Arguments entered:
./blackjack 400 1
Should work for any numbers.
Shouldn't argv[0] would be blackjack, argv[1] the first number and argv[2] the second?

cout doesn't fill the elements of argv, those come from the command line used to execute your program. Also, whenever you use argv, be sure to check argc, which is the number of valid indices into argv. Your program is probably crashing because you haven't passed any arguments to your program, and so the elements of argv aren't usable.
You'll need to use cin calls to read the user input that you're expecting, or change your program to use values passed in from the command line, i.e. no prompts or reads.
Your added assumptions are correct about argv: if you execute the program with: ./blackjack 400 1, then argv[1] should be 400, and argv[2] should be 1.
Since, based on your edit, you seem to want to get these numbers from the command-line, then remove your cout calls.

As others have noted argv are command line arguments. If they are filled you just use them. I often do like this:
int
main(int n_app_args, char** app_arg)
{
std::string nec_file;
if (n_app_args > 1)
nec_file = app_arg[1];
else
{
std::cout << "Enter NEC output file: ";
std::cin >> nec_file;
}
where if I forget the command line argument the program asks me. If I remember the argument the argument is used without further intervention. You can obviously extend this to more arguments.

Related

Processing command line arguments for a code in c++ for random and user input

Our instructor requires us to input data into code in the following ways:
1.Random mode
Run with graphs generated by random number generator. The command line for
this mode is:
$ mst –r n d
// run in a random connected graph with n vertices and d% of density.
// See Performance measurements section for details.
2.User Input mode
$mst -s file-name // read the input from a file ‘file-name’ for simple scheme
$mst -f file-name // read the input from a file ‘file-name’ for f-heap scheme
At present I have written the code and compiled it using g++:
g++ -o mst.o mst.cpp
I am taking input from the file like this:
./mst.o < data.txt
However, I don't know how to go about satisfying the above requirements.
An application starts in main like this:
int main(int argc, char* argv[])
These are the command line arguments.
You can print them out if you want:
int main(int argc, char* argv[])
{
std::cout << "Application: " << argv[0] << "\n";
for(int loop =1 ;loop < argc; ++loop)
{
std::cout << "\tArg: " << loop << " Value: " << argv[loop] << "\n";
}
}
You need to check the argc and argv parameters to main. If argv is large enough, check argv[1] to see if it's one of the switches you need to handle. If it is then decode the other argv for the numbers or filenames that you need. argv[0] is generally the name of the executable and isn't used.

Why is my command line argument handling crashing my program?

Why is something so seemingly simple is crashing my program?
I am trying to get a value for n to make an array the size of N and perform various operations on it, but that's beside the point. Anyways, It keeps crashing every time I try to access argv[1].
int main(int argc, char * argv[])
{
int n;
n = atoi(argv[1]); //Crashes here!
cout << "\nN: " << n << endl;
}
Does argv[1] exist? To prevent your code from accessing memory it should not check how many arguments were passed.
if(argc >= 2)
n = argv[1];
else
std::cout << "Proper usage: .....\n";
This seems like a great time to learn how to use your debugger to view the contents of argv and argc.

How to use getopt_pp in c++?

I know this is a noob question. I used this example code from here. How is it supposed to work? I thought you can input something for who but it just closes immediately.
#include <iostream>
#include "getopt_pp_standalone.h"
using namespace GetOpt;
using namespace std;
int main(int argc, char* argv[])
{
string who;
GetOpt_pp ops(argc, argv);
ops >> Option('n', "name", who, "world" ); /* the default name is 'world' */
cout << "Hello " << who << "!" << endl;
return 0;
}
Variants of getopt get options from the command line rather than input by a user.
You will need to run your program with something like:
myprog -n Pax
If you want interactive input from the user, get rid of the getopt stuff altogether and just use the streams, such as:
std::cout << "Identify yourself, interloper!\n";
std::cin >> who;
std::cout << "Hello, " << who << ", my name is Pax.\n";
A few other things to impart:
First, you may need to put a getchar() (or cin >> who) before the return if you're running in an IDE that closes the execution window instead of waiting. Otherwise, the output will go to the window and immediately disappear.
Second, while it's probably okay for small programs, using namespace std can cause problems with more substantial projects (in terms of polluting the standard namespace, see here for a good explanation). I prefer to fully qualify my calls, such as:
std::cout << "blah, blah, blah\n";
Third, endl is used far too often by most developers. Most times you should just either use '\n' instead, or just tack on \n to the end of a string like "Hello, world!\n". That's because the \n way doesn't force possibly inefficient flushing of the stream like endl does. That's covered here.

Why does my program crash if I don't give command line arguments to it? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I made a simple test program to play around with C++11 threads.
#include <iostream>
#include <stdlib.h>
#include <thread>
using namespace std;
void tee(int civ)
{
for(int loop=0; loop<19; loop++, civ++)
{
civ = civ%19;
cout << loop << "\t" << civ << endl;
this_thread::sleep_for(chrono::milliseconds(300));
}
}
void koot()
{
while(true)
{
cout << ":) ";
this_thread::sleep_for(chrono::milliseconds(300));
}
}
int main(int argc, char *argv[])
{
thread saie(tee, atoi(argv[1])),
kamaa(koot);
saie.join();
kamaa.join();
return 0;
}
It works fine as long as I supply command line arguments, but if I don't, it crashes.
How can this be solved?
I tried checking the argument count, and if they existed, to no avail.
EDIT: I had to add this line:
if(argc < 2) return 1;
It crashes because you are accessing
argv[1]
which would hold a command line argument (other than the program's name) if there was one. You should check whether argc is greater than 1. Why greater than 1? Because the first command line argument is the name of the program itself. So argc is always greater than 0. And indexing starts at 0. So if argc == 1, only argv[0] is valid.
#include <iostream>
int main(int argc, char* argv[])
{
// no need to check argc for argv[0]
std::cout << argc << " " << argv[0] << "\n";
}
argv[1] is null, causing a crash in the call to atoi(). Note that array indices in C++ are zero-based!
because you don't check if argc > 1 and you try to access argv[1]
way to solve this is first check if argc > 1 and then access argv[1].
int main(int argc, char *argv[])
{
if(argc > 1){
thread saie(tee, atoi(argv[1])),
kamaa(koot);
saie.join();
kamaa.join();
}
return 0;
}
Points to remember:
argc is by default 1. This is the argument counter that holds the no. of arguments passed to the program. By default, its 1 because the program gets the executable's name(and path)
argv holds the array of NULL terminated character arrays(or strings). argv[0] will always hold the name of the executable.
never assume user will always enter the arguments. and always do a bounds check while accessing argv or any array in the future.
Try the following code instead:
int main(int argc, char *argv[])
{
if(argc < 2) { cout<<"No command line arguments found\n Aborting!\n"; return 1;}
else { thread saie(tee, atoi(argv[1])),kamaa(koot);}
saie.join();
kamaa.join();
return 0;
}
You are trying to access a command line argument argv[1] which is not present. It is always better to check if the command line argument exists or not.

integer arguments for c++

I have a sort of calculator in C++ that should accept arguments when executed. However, when I enter 7 as an argument, it might come out to be 10354 when put into a variable. Here is my code:
#include "stdafx.h"
#include <iostream>
int main(int argc, int argv[])
{
using namespace std;
int a;
int b;
if(argc==3){
a=argv[1];
b=argv[2];
}
else{
cout << "Please enter a number:";
cin >> a;
cout << "Please enter another number:";
cin >> b;
}
cout << "Addition:" << a+b << endl;
cout << "Subtaction:" << a-b << endl;
cout << "Multiplycation:" << a*b << endl;
cout << "Division:" << static_cast<long double>(a)/b << endl;
system("pause");
return 0;
}
Wherever did you get int argv[]? The second argument to main is char* argv[].
You can convert these command line arguments from string to integer using strtol or to floating-point using strtod.
For example:
a=strtol(argv[1], nullptr, 0);
b=strtol(argv[2], nullptr, 0);
But you can't just change the parameter type, because the operating system is going to give you your command-line arguments in string form whether you like it or not.
NOTE: You must #include <stdlib.h> (or #include <cstdlib> and using std::strtol;) to use the strtol function.
If you want error-checking, use strtol instead of atoi. Using it is almost as easy, and it also gives you a pointer to the location in the string where parsing terminated. If that points to the terminating NUL, parsing was successful. And of course it is good that you verify argc to make sure the user provided enough parameters, and avoid trying to read missing parameters from argv.
Example of error checking:
char* endp;
a = strtol(argv[1], &endp, 0);
if (endp == argv[1] || *endp) { /* failed, handle error */ }
The function signature is int main(int argc, char *argv[]). argv is an array of string pointers.
If the argument is 7, it will be in the form of a string ("7"). Use atoi() to convert it to the number 7.
Second argument in the main should either either be char* argv[] or char** argv. Then you have to have convert them to int.