I have the following piece of simple code in the main() function.
Unfortunately, I cannot get main() to wcout the converted wchar_t array. Why is this so?
int main(int argc, wchar_t *argv[])
{
std::wcout << "first argument: " << std::wstring(argv[1])
}
this just prints
first argument:
Related
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.
I need to get an argument and convert it to an int. Here is my code so far:
#include <iostream>
using namespace std;
int main(int argc,int argvx[]) {
int i=1;
int answer = 23;
int temp;
// decode arguments
if(argc < 2) {
printf("You must provide at least one argument\n");
exit(0);
}
// Convert it to an int here
}
Since this answer was somehow accepted and thus will appear at the top, although it's not the best, I've improved it based on the other answers and the comments.
The C way; simplest, but will treat any invalid number as 0:
#include <cstdlib>
int x = atoi(argv[1]);
The C way with input checking:
#include <cstdlib>
errno = 0;
char *endptr;
long int x = strtol(argv[1], &endptr, 10);
if (endptr == argv[1]) {
std::cerr << "Invalid number: " << argv[1] << '\n';
} else if (*endptr) {
std::cerr << "Trailing characters after number: " << argv[1] << '\n';
} else if (errno == ERANGE) {
std::cerr << "Number out of range: " << argv[1] << '\n';
}
The C++ iostreams way with input checking:
#include <sstream>
std::istringstream ss(argv[1]);
int x;
if (!(ss >> x)) {
std::cerr << "Invalid number: " << argv[1] << '\n';
} else if (!ss.eof()) {
std::cerr << "Trailing characters after number: " << argv[1] << '\n';
}
Alternative C++ way since C++11:
#include <stdexcept>
#include <string>
std::string arg = argv[1];
try {
std::size_t pos;
int x = std::stoi(arg, &pos);
if (pos < arg.size()) {
std::cerr << "Trailing characters after number: " << arg << '\n';
}
} catch (std::invalid_argument const &ex) {
std::cerr << "Invalid number: " << arg << '\n';
} catch (std::out_of_range const &ex) {
std::cerr << "Number out of range: " << arg << '\n';
}
All four variants assume that argc >= 2. All accept leading whitespace; check isspace(argv[1][0]) if you don't want that. All except atoi reject trailing whitespace.
Note that your main arguments are not correct. The standard form should be:
int main(int argc, char *argv[])
or equivalently:
int main(int argc, char **argv)
There are many ways to achieve the conversion. This is one approach:
#include <sstream>
int main(int argc, char *argv[])
{
if (argc >= 2)
{
std::istringstream iss( argv[1] );
int val;
if (iss >> val)
{
// Conversion successful
}
}
return 0;
}
std::stoi from string could also be used.
#include <string>
using namespace std;
int main (int argc, char** argv)
{
if (argc >= 2)
{
int val = stoi(argv[1]);
// ...
}
return 0;
}
As WhirlWind has pointed out, the recommendations to use atoi aren't really very good. atoi has no way to indicate an error, so you get the same return from atoi("0"); as you do from atoi("abc");. The first is clearly meaningful, but the second is a clear error.
He also recommended strtol, which is perfectly fine, if a little bit clumsy. Another possibility would be to use sscanf, something like:
if (1==sscanf(argv[1], "%d", &temp))
// successful conversion
else
// couldn't convert input
note that strtol does give slightly more detailed results though -- in particular, if you got an argument like 123abc, the sscanf call would simply say it had converted a number (123), whereas strtol would not only tel you it had converted the number, but also a pointer to the a (i.e., the beginning of the part it could not convert to a number).
Since you're using C++, you could also consider using boost::lexical_cast. This is almost as simple to use as atoi, but also provides (roughly) the same level of detail in reporting errors as strtol. The biggest expense is that it can throw exceptions, so to use it your code has to be exception-safe. If you're writing C++, you should do that anyway, but it kind of forces the issue.
Take a look at strtol(), if you're using the C standard library.
The approach with istringstream can be improved in order to check that no other characters have been inserted after the expected argument:
#include <sstream>
int main(int argc, char *argv[])
{
if (argc >= 2)
{
std::istringstream iss( argv[1] );
int val;
if ((iss >> val) && iss.eof()) // Check eofbit
{
// Conversion successful
}
}
return 0;
}
Like that we can do....
int main(int argc, char *argv[]) {
int a, b, c;
*// Converting string type to integer type
// using function "atoi( argument)"*
a = atoi(argv[1]);
b = atoi(argv[2]);
c = atoi(argv[3]);
}
In my opinion this is the most practical way to pass your variables. Using std::stoi. It's good practice to use std:: and NOT to use namespace; this is why I can define a string with "string" as the variable name
#include <iostream>
#include <string>
int main(int argc, char **argv)
{
std::string string{argv[1]};
int integer1{std::stoi(argv[2])};
int integer2{std::stoi(argv[3])};
int sum{integer1 + integer2};
std::cout << string << " sum " << sum;
}
Example:
./out this 40 1 // input
this sum 41 // output
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.
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.
How can I parse integers passed to an application as command line arguments if the app is unicode?
Unicode apps have a main like this:
int _tmain(int argc, _TCHAR* argv[])
argv[?] is a wchar_t*. That means i can't use atoi. How can I convert it to an integer? Is stringstream the best option?
if you have a TCHAR array or a pointer to the begin of it, you can use std::basic_istringstream to work with it:
std::basic_istringstream<_TCHAR> ss(argv[x]);
int number;
ss >> number;
Now, number is the converted number. This will work in ANSI mode (_TCHAR is typedef'ed to char) and in Unicode (_TCHAR is typedef`ed to wchar_t as you say) mode.
Dry coded and I don't develop on Windows, but using TCLAP, this should get you running with wide character argv values:
#include <iostream>
#ifdef WINDOWS
# define TCLAP_NAMESTARTSTRING "~~"
# define TCLAP_FLAGSTARTSTRING "/"
#endif
#include "tclap/CmdLine.h"
int main(int argc, _TCHAR *argv[]) {
int myInt = -1;
try {
TCLAP::ValueArg<int> intArg;
TCLAP::CmdLine cmd("this is a message", ' ', "0.99" );
cmd.add(intArg);
cmd.parse(argc, argv);
if (intArg.isSet())
myInt = intArg.getValue();
} catch (TCLAP::ArgException& e) {
std::cout << "ERROR: " << e.error() << " " << e.argId() << endl;
}
std::cout << "My Int: " << myInt << std::endl;
return 0;
}
A TCHAR is a character type which works for both ANSI and Unicode. Look in the MSDN documentation (I'm assuming you are on Windows), there are TCHAR equivalents for atoi and all the basic string functions (strcpy, strcmp etc.)
The TCHAR equivalient for atoi() is _ttoi(). So you could write this:
int value = _ttoi(argv[1]);
I personally would use stringstreams, here's some code to get you started:
#include <sstream>
#include <iostream>
using namespace std;
typedef basic_istringstream<_TCHAR> ITSS;
int _tmain(int argc, _TCHAR *argv[]) {
ITSS s(argv[0]);
int i = 0;
s >> i;
if (s) {
cout << "i + 1 = " << i + 1 << endl;
}
else {
cerr << "Bad argument - expected integer" << endl;
}
}