I will try to explain what I want to do. I've got the program (which doesn't work), which is written to be called from CMD console in windows. I'm using parameters from main function
int main(int argc, char *argv[])
But in this case I can't use the debugger to find what i'm doing wrong...
Am I able to somehow connect char *argv[] argument to created table in code ?
Example:
int main(int argc, char *argv[])
{
char tablica[] = { 'K','2','+','1','-','3','*','(','3','+','2',')','*','2' };
tablica = **argv; //// IDK HOW TO CONNECT THESE TWO
here's how you can fake argument passing and substitute with your array
#include <stdio.h>
int main(int argc, char* argv[]){
char *tablica[] = { argv[0],"K","2","+","1","-","3","*","(","3","+","2",")","*","2" };
int i;
argv=tablica;
argc=sizeof(tablica)/sizeof(tablica[0]);
for (i=0;i<argc;i++)
{
printf("%s\n",argv[i]);
}
return 0;
}
result:
your_executable
K
2
+
1
-
3
*
(
3
+
2
)
*
2
notes: in order to be compliant with argc,argv:
I have changed the array of chars to an array of char * (single quotes => double quotes). That seems logical, since without that you could not pass for instance numbers > 9 in your arguments!
I have overridden argc as well (automatic computation from your array)
I have inserted program name in your array, else it would shift argument parsing.
You can do better by separating your code into a testable function. This will allow you to write a unit test project to see if it behaves correctly on known inputs (as you have already prepared), or call it directly from main with argc, argv.
// your code
int your_code (int argc, char* argv[]);
// can be called from main
int main(int argc, char* argv[]){
your_code(argc, argv);
return 0;
}
// or can be tested
void unit_test() {
char * tablica[] = ...;
int arg_count = sizeof(tablica) / sizeof(tablica[0]);
your_code(arg_count, tablica);
}
Note that your code currently assumes that each character is a new element. This prevents numbers larger than 9. If you're committed to that a string does this for you pretty simply.
const auto tablica = string(argv + 1, argc - 1) + "K2+1-3*(3+2)*2"s
Or if you wanted your command line arguments as the suffix:
const auto tablica = "K2+1-3*(3+2)*2"s + string(argv + 1, argc - 1)
If you need to dump this into a separated list you can do:
copy(cbegin(tablica), cend(tablica), ostream_iterator<char>(cout, "\n"))
Related
I'd like to be able to save argv into a struct so that it can be passed to functions like so:
struct Parameters {
int argc;
char * argv[];
};
void Start(
Parameters P
) {
};
int main (
int argc,
char * argv []
) {
Parameters P;
P.argc = argc;
P.argv = & argv;
return 0;
}
But with:
clang++ -std=c++2a -stdlib=libc++ -rtlib=compiler-rt -Ofast Start.cpp -o Start && ./Start;
I'm getting this error:
Start.cpp:21:9: error: array type 'char *[]' is not assignable
Is there a way of saving argv to a variable? Any help would be very much appreciated.
A simple way is to convert it to a vector of strings:
int main(int argc, char* argv[])
{
// Note: use argv + 1 to skip the application name in args.
// If you want to include the application name then don't use
// the +1
std::vector<std::string> args(argv + 1, argv + argc);
// Now this can be passed to functions easily.
// args.size() == number of arguments.
// args[x] == the string for argument x
}
You can simply change to:
struct Parameters
{
int argc;
char ** argv;
};
Your argv array of pointers to char will decay to a pointer to pointer to char.
Then, your main becomes simpler, with:
P.argv = argv;
I have a const char** called glfwNames which holds the C version of a string array of the required GLFW library extensions. Would it be possible to loop through either the const char* (string), or the individual characters of the string separated by '\0'?
const char** glfwNames = glfwGetRequiredInstanceExtensions(&glfwCount)
for (const char** name = glfwNames; *name; ++name)
{
slog("GLFW Extensions to use: %s", *name);
}
This is what I've attempted from one of the answers, and the return value of
glfwGetRequiredInstanceExtensions
is an array of extension names, required by GLFW http://www.glfw.org/docs/latest/group__vulkan.html#ga1abcbe61033958f22f63ef82008874b1
If glfwNames is nullptr-terminated:
#include <cstdio>
int main()
{
char const *glfwNames[] = { "foo", "bar", "baz", nullptr };
for (char const **p = glfwNames; *p; ++p)
std::puts(*p);
}
If you *know* the number of strings:
std::uint32_t glfwCount;
const char** glfwNames = glfwGetRequiredInstanceExtensions(&glfwCount)
for (std::uint32_t i{}; i < glfwCount; ++i)
{
slog("GLFW Extensions to use: %s", glfwNames[i]);
}
To also loop through the individual chars:
for (std::uint32_t i{}; i < glfwCount; ++i)
{
for(char const *p{ glfwNames[i] }; *p; ++p)
std::putchar(*p);
}
A common pattern that I use to loop through the arguments to main is via std::for_each:
#include <algorithm>
int main(int argc, char* argv[]) {
std::for_each( argv + 1, argv + argc, handler );
}
where handler is any function taking a const char*, const std::string&, or std::string_view (I use the later).
Would a similar approach work for your problem? Notice that this approach requires you to know the length of your array of strings.
As a side note, it is important to know that the return argument of std::for_each is the function provided (handler in this case). That enables the suggested pattern to make a last call once the input is known to have been exhausted:
#include <algorithm>
int main(int argc, char* argv[]) {
std::for_each( argv + 1, argv + argc, handler )("Argument To Last Call");
}
This can be used to implement state machines that receive the termination trigger at the end.
In a C++ application, the arguments are all stored in a char* array, like so:
int main(int argc, char* argv[])
{
...
}
However, a lot of people prefer the convenience of string manipulation, but it would be a hastle to have to convert every char* into a std::string every time. So my question is, how do convert a char*[] into a std::string[], so that you don't have to convert them all individually as you progress in your program?
If you accept std::vector, you can use its range constructor.
std::vector<std::string> args(argv, argv + argc);
You can loop through the arguments.
int main(int argc, char* argv[]) {
std::string *s = new std::string[argc];
for (int i = 0; i < argc; ++i)
s[i] = argv[i];
}
How can I put the default values for main function arguments like the user defined function?
Well, the standard says nothing which prohibits main from having default arguments and say you've successfully coalesced the compiler to agree with you like this
#include <iostream>
const char *defaults[] = { "abc", "efg" };
int main(int argc = 2, const char **argv = defaults)
{
std::cout << argc << std::endl;
}
Live example. It compiles with no errors or warnings, still it's useless; a futile experiment. It almost always would print 1.
Every time you invoke the program, say, with no arguments (or any number of arguments for that matter), argc gets set to 1 and argv[0] points to the program name, so doing it is pointless i.e. these variables are never left untouched and hence having defaults makes little sense, since the defaults would never get used.
Hence such a thing is usually achieved with local variables. Like this
int main(int argc, char **argv)
{
int const default_argc = 2;
char* const default_args[] = { "abc", "efg" };
if (argc == 1) // no arguments were passed
{
// do things for no arguments
// usually those variables are set here for a generic flow onwards
argc = default_argc;
argv = default_args;
}
}
I think you want to do two different things for the following cases.
When no arguments are passed
When arguments are passed.
Here is how you do it.
int main(int argc, char *argv[])
{
if(argc == 1)
{
// case #1
}
else
{
// case #2
}
}
Using argc and argv? Thoses will pass argument from the command line to your program. You can't really use default arguments. You have to pass them during the call to your program like this :
$> ./my_addition "4" "7"
int main(int argc, char *argv[])
{
// argc <=> 'argument count' (=3)
// argv <=> 'argument vector' (i.e. argv[1] == "4")
// argv[0] is usually the bin name, here "my_addition"
for (int i = 0; i < argc; ++i)
std::cout << argv[i] << std::endl;
return (0);
}
Maybe you could use a script to run your program, this could maybe be the closest solution to default argument for main().
exec_my_prog.sh:
#!/bin/zsh
call_your_program + very_meny_args
And calling ./exec_my_prog.sh would run your program with the "default" arguments.
I have a program that reads in a single argument from the command line and performs certain operations on it. I'm using argv and argc. When I fail to pass an argument to the program, it segfaults. I've tried checking if argc isn't a certain value and then printing the value out, but it still segfaults. Here's the code in question. Note that it works as expected when passed a single argument. Here's the code in question:
int main(int argc, char *argv[])
{
int numTimes = atoi(argv[1]); //converts content of argv[1] into integer
if(argc != 2)
{
printf("Enter a valid integer.");
}
You need to check argc before you try to access that argument. Just move the argc test to sometime before before you call atoi(argv[1]).
Just check the number of arguments before trying to accessing a specific element. Something like this:
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("Enter a valid integer.");
return 0;
}
int numTimes = atoi(argv[1]); // now we're sure to have at least 1 argument passed
// ...
}
You have to do the check before attempting to access the arguments.