c++ error: change from command line input to variable input - c++

I want to change from command line input to variable input.
int main(int argc, char *argv[])
{
std::cout << argc << std::endl;
std::cout << argv[0] << std::endl;
std::cout << argv[1] << std::endl;
}
Change to this, but when I want to compile this an error appears.
int main()
{
int argc = 2;
char *argv[] = 0;
argv[0] = "./server";
argv[1] = "127.0.0.1";
}
This error appears: error: array initializer must be an initializer list
char *argv[] = 0;

You have to provide the size of the array, since you did not provide an initializer from which the compiler can deduce the size. Again, from C++11 you cannot have a string-literal bind to char*, use const char*.
int main()
{
constexpr int argc = 2;
const char *argv[argc] = {};
argv[0] = "./server";
argv[1] = "127.0.0.1";
}
You may want to explore good use of std::array<std::string, 2> instead.

Related

C++ add checks to avoid reading two arguments

My code currently reads both arguments and i need to add a check for it to read 1 argument if someone put in one number such as 100 and to read the second argument if entered 100 3.
right now it reads both arguements everytime and and gives an error if one argument is entered.
#include <iostream>
#include <cstring>
using namespace std;
int perfectnumber(int number)
{
int sumofdivisor = 0;
for (int i = 1; i < number; i++)
{
if (number % i == 0)
sumofdivisor += i;
}
return abs(sumofdivisor - number);
}
int main(int argc, char *argv[])
{
int count = atoi(argv[2]);
int upper_limit = atoi(argv[1]);
for (int start = 2; start <= upper_limit; start++)
{
int difference = perfectnumber(start);
if (difference <= count)
{
cout << start << " ";
}
}
cout << endl;
}
The parameter argc is your friend, it tells you how many arguments there are.
Here is an example of how to use argc.
#include "stdio.h"
int main(int argc, char* argv[])
{
printf("Number: %d\n", argc);
printf("0: %s\n", argv[0]);
if (1<argc)
{
printf("1: %s\n", argv[1]);
}
}
You can use argc to see how many arguments are provided. The first argument is the name of the executable1, so you have to compare with 3. Here is a simple example:
#include <iostream>
#include <cstdlib>
int main(int argc, char *argv[])
{
if (argc < 3) {
std::cerr << "Too few arguments\n";
return EXIT_FAILURE;
}
std::cout << "Args: " << argv[1] << " and " << argv[2] << '\n';
}
1 This is not entirely correct. According to this reference: "argv[0] is the pointer to the initial character of a null-terminated multibyte string that represents the name used to invoke the program itself (or an empty string "" if this is not supported by the execution environment)." But as a comment points out, this is not entirely accurate either. This is a convention that implementations usually follow but are free to not to.

how to operate on global variables in c++

I need help with global vars in C++. I am passing an empty argv array into a parse function and I am trying to fill it, however when I access argv back in main, argv[0] comes back empty no matter what I enter in. Please help.
static int argc;
static char* argv[100];
void parse(string str, int argc, char* argv[])
{
argc = 0;
char * cstr = new char [str.length()+1];
strcpy (cstr, str.c_str());
char * p = strtok (cstr," ");
int i = 0;
while (p!=0)
{
argc++;
argv[i] = p;
p = strtok(NULL," ");
i++;
}
delete[] cstr;
}
int main( void )
{
string theLine;
while (true)
{
cout << "myshell> ";
getline(cin,theLine);
cout << "Command was: " << theLine << endl;
if ((theLine == "exit") || (cin.eof()) || (theLine == "quit"))
exit(0);
parse(theLine, argc, argv);
cout << "argv[0] " << argv[0] << "\n";
}
}
I am trying to assign character strings to argv inside the parser function but when I go to access it in MAIN, it comes out blank. How do I achieve what I am trying to do? It has to do with global variables but I cannot figure out how.
The problem is that you're storing pointers into cstr in argv, but then you're deleting cstr at the end of the parse() function. Get rid of:
delete[] cstr;
Also, you should pass argc by reference. Otherwise, when you update it in the parse() function it won't update the caller's variable. So it should be:
void parse(string str, int &argc, char *argv[])
However, you also have a memory leak. You're creating a new cstr each time parse is called, but never deleting it. You should change the function to return cstr, and have the caller delete it when they're done with that parsed line.
char *parse(str str, int &argv, char *argv[]) {
...
return cstr;
}
Then in your main() loop, do:
int main( void )
{
string theLine;
while (true)
{
cout << "myshell> ";
getline(cin,theLine);
cout << "Command was: " << theLine << endl;
if ((theLine == "exit") || (cin.eof()) || (theLine == "quit"))
exit(0);
char *cstr = parse(theLine, argc, argv);
cout << "argv[0] " << argv[0] << "\n";
delete[] cstr;
}
}
You are confused about how global and local variables of the same name interact.
Let me start by saying that there are two distinct objects each named argc and two distinct objects each named argv.
The first set are the global variables
static int argc;
static char* argv[100];
The second set are the parameters of your parse function
void parse(string str, int argc, char* argv[])
{
argc = 0;
...
}
I've taken one line from parse. What that does is actually set the object in the argc parameter to 0. The object in the global argc is not set to 0 by this.
Let's rename some of the variables in the above snippet to see clearly which name belongs to which object/place:
static int global_argc;
static char* global_argv[100];
void parse(string str, int argc, char* argv[])
{
argc = 0;
...
}
Now, notice how I changed the first two to global_, but the rest (all of the, even the ones not shown) remain argc and argv.
You need to start by learning about variable scope. Once arrays and pointers are involved, such as argv, things get even more complicated. I could not possibly explain all of this to you in one answer, except for: first learn more about variables and variable scope. Then learn about pointers and arrays. Then come back to this program and see if you can fix it, which is not something you can do at this point in time.
It may take a little more time, and a little more work, but don't get discouraged.

How to pass an argument to the C++ application

In Java you can pass an argument with void main(String[] args).
Find run configuration in Eclipse, put arguments and run a program, but in C++ there is just int main() how to pass arguments to the program using Visual Studio 2010?
While int main() is correct, you can use int main(int argc, char *argv[]) or int main(int argc, char **argv) to get the argument count with argc and an array of char arrays (strings) with argv.
Please note that the first argument will always be the path to the program you are running.
It'you can refer to any basic c++ programs in any tutorial for this.
argc- number of argument count
argv- argumant list
Below is sample code to parse argument list.
#include <iomanip>
#include <iostream>
using namespace std;
int main( int argc, char* argv[] )
{
cout << "The name used to start the program: " << argv[ 0 ]
<< "\nArguments are:\n";
for (int n = 1; n < argc; n++)
cout << setw( 2 ) << n << ": " << argv[ n ] << '\n';
return 0;
}
If you are using visual studio there is a command line property using which you can pass commandline parms
Sample code :
// command_line_arguments.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
int main( int argc, // Number of strings in array argv
char *argv[], // Array of command-line argument strings
char *envp[] ) // Array of environment variable strings
{
int count;
// Display each command-line argument.
cout << "\nCommand-line arguments:\n";
for( count = 0; count < argc; count++ )
cout << " argv[" << count << "] "
<< argv[count] << "\n";
}
Read more about argument parsing in c++ read Parsing C++ Command-Line Arguments in MSDN. there are example input output also.

Comparing std::string with constants vs comparing char arrays with constants In C++

I am trying to make a little text adventure to get a handle on C++.
cin >> keyboard1;
if ((keyboard1 == "inv")inventory(inv);
This will work if keyboard1 is a string, but won't if it's a char array, is this because I haven't included the null at the end of the constant?
Let'say your code is the following:
int main(int argc, char *argv[])
{
std::string s;
std::cin >> s;
std::cout << s << std::endl;
if (s == "inv") {
std::cout << "Got it" << std::endl;
}
return 0;
}
This works as expected because of the way the stl class string overrides the == operator.
You cannot expect the following code to work instead:
int main(int argc, char *argv[])
{
char *s = (char *)calloc(10, sizeof(char));
std::cin >> s;
std::cout << s << std::endl;
if (s == "inv") {
std::cout << "Got it" << std::endl;
}
return 0;
}
because you are comparing s, which is the address where the string starts to a constant string (which, by the way, is automatically null-terminated by the compiler).
You should use strcmp to compare "c-strings":
int main(int argc, char *argv[])
{
char *s = (char *)calloc(10, sizeof(char));
std::cin >> s;
std::cout << s << std::endl;
if (strcmp(s, "inv") == 0) {
std::cout << "Got it" << std::endl;
}
return 0;
}
This works.
No, the reason it won't work is because you will be comparing the address of the memory that represents each string. Use strcmp / wcscmp instead.
The reason why comparing a string and a constant work is because the string class will have an equality operator defined (e.g. bool StringClass:operator==(const char* pszString)).
If keyboard1 is a char array, then if (keyboard1 == "inv") is performing a simple pointer comparison (both become char*).
When keyboard1 is a string, it can call an operator==(cosnt string&, const char*) if one exists, otherwise, if the string has the non-explicit constructor string(const char *s), the constant "inv" would be implicitly converted to a string object, and operator==(const string&,const string&) applied.

C++, command line, parameters

I am starting my c++ program from command line:
program input_file1 input_file2 output_file
where
int main( int argc, char *argv[] )
{
short indicator= 3;
char input_file1[4096], input_file2[4096], output_file[4096];
char *p_file = NULL;
while ( --argc > 0 ) {
switch (--indicator) {
case 2:
p_file = output_file;
break;
case 1:
p_file = input_file2;
break;
case 0:
p_file = input_file1;
break;
}
for (char *argument = argv[argc]; ; ++argument) {
if (*argument == '\0')
break;
else
*p_file++ = *argument;
}
*p_file = '\0';
}
std::cout << input_file1 << '\n';
std::cout << input_file2 << '\n';
std::cout << output_file << '\n';
}
But with the real arguments
program D:\\data\\file1.txt D:\\data\\file2.txt D:\\data\\file3.txt
in names of the files only the first letter D is stored...
Output:
D
D
D
Thanks for your help...
Ok, so here is the short version:
int main(int argc, char *argv[]) {
if (argc != 2) {
std::cout << "This program requires 1 argument!" << std::endl;
return 1;
}
std::string input_file(argv[1]);
std::cout << input_file << std::endl;
}
You should be able to take it from here.
This is a C problem, not a C++ one, but as it is tagged C++, i will suggest a C++ solution for your problemĀ :
int main( int argc, char *argv[] ) {
std::vector<std::string> args(argv+1, argv+argc);
std::cout << args[0] << '\n' << args[1] << '\n' << args[2] << std::endl;
}
UPDATE using iterators on argv to fill the vector args (thanks Space_C0wb0y)
Rather than copying the arguments, just set the file names to point to the appropriate entry in argv.
int main(int argc, char *argv[]) {
char *input_file1, *input_file2, *output_file;
if (4 > argc)
{
std::cout << "Not enough parameters\n";
return -1;
}
input_file1 = argv[1];
input_file2 = argv[2];
output_file = argv[3];
std::cout << input_file1 << '\n';
std::cout << input_file2 << '\n';
std::cout << output_file << '\n';
}
the contents of argv will exist for as long as the program is running.
*p_file ++ = * argument;
This assigns the first character of arguement to the first character in p_file.
You need to use strcpy, or declare some std::strings instead of arrays of char
Your loop is all wrong. You are looping through characters, not the parameter array. You can do that like this:
for(auto arg = argv + 1; *arg; ++arg)
{
std::cout << (*arg) << '\n'; // *arg is a char*
}
This works because the arguments (if any) start at argv + 1 and because they are null terminated so that *arg is nullptr (converts to false) at the end of the argument array.
Your arguments are obtained by dereferencing arg using *arg which is a char*.
So you can do:
if(!std::strcmp(*arg, "--help"))
print_help_info();