The problem that i have is that i have to write a hanois tower game in c and the input for the number of the rings must not be in the programm but the code must read the number of rings in the execution.
Example: ./hanoistower 3
And the code should get the 3 as the input. How can i do that?
Command line arguments are propagated as strings through the main() function of your C program.
In int main(int argc, char *argv[]) argc is the number of arguments, and argv is an array of strings containing the arguments. Note that the program name itself is always the first "argument".
As the arguments are passed as strings, you likely need to convert your 3 to an integer, which can be done with the atoi function. Here's a start:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int rings;
if(argc != 2) {
printf("Usage: %s number-of-rings\n",argv[0]);
return 1;
}
rings = atoi(argv[1]);
printf("Using number-of-rings = %d\n", rings);
...
return 0;
}
I strongly suggest reading a good C programming book (in 2020, Modern C).
It will be much faster than asking questions here. Don't forget to also read the documentation of your C compiler (perhaps GCC), your build automation tool (e.g. GNU make or ninja), and debugger (perhaps GDB). If you code on and for Linux, read also Advanced Linux Programming and syscalls(2), and the documentation of GNU glibc (or of musl-libc, if you use it).
Hovever, the program arguments is given as a null terminated array of strings to the main function, which is usually declared as
int main (int argc, char**argv) { /*...*/ }
if you run your program with ./hanoistower 3 and if your hanoistower.c is your source code (which you need to compile with debugging and warning enabled, i.e. gcc -Wall -g hanoistower.c -o hanoistower on Linux) then you have one extra argument, so
argc == 2
argv[0] is the "./hanoistower" string
argv[1] is the "2" string (use atoi to convert it to an int)
argv[2] is NULL
Please, please learn to use the debugger (gdb on Linux).
Just add, argc and argv to the list of main method parameters, as shown below:
int main ( int argc, char *argv[] )
Then use argv as the variable to specify number of rings inside your code.
Related
For example,
Input:
echo( hello world
Program:
#include<stdio.h>
int main(int n,char** args){
// Replace all the '\0' with ' '
system(args[1]);
return printf("\n");
}
Output:
hello world
Now I need hello world in a pointer.
I know that **char doesn't work the way I want it to..
But is there any efficient way out, instead of calculating the length of each argument, malloc-ing those many bytes and then concatenating it to the allocated memory?
Some access specifier for char** maybe?
I am trying to add echo( a command to DOSBox, so basically echo params and then print a newline. That's it.
Also, is there any way to exclude to recognize an exe without any spaces or is it console specific?
To echo an empty line, in Windows cmd, the best method is echo(, but also common are echo/, echo. and some more variations.
The (best for cmd) echo( doesn't work in DOS (results in a bad command or filename error), but echo/ works fine even in DOS.
Make it one line.
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char oneline[256] = "";
for(int index = 1; index < argc; index++)
{
strcat(oneline, argv[index]);
strcat(oneline, " ");
}
printf("parameters: "%s"\n", oneline);
}
https://godbolt.org/z/B4ULLB
This is only the idea and it can be done much more efficiently - for example by not using strcat or more efficiently allocate the memory. But the idea will be the same. You can also do not add the last space (it is for nitpickers)
I want a way to get all the arguments in a single pointer, a string that's terminated at the end.
Using either form of the main() function:
int main(int argc, char *argv[]) {...};
int main(int argc, char **argv) {...};
which are equivalent signatures for the C main() function, will allow you to pass any number of arguments, each of any size. If you want to pass a single string containing many arguments just pass a single string with some kind of delimiter. If the delimiter is a space ( " " ), then by definition of the behavior of the C main() function command line argument requires surrounding them with ":
Say your exe name is prog.exe
prog this,is,one,argument
prog "this is one argument" //double quotes provide cohesion between space delimited command line arguments
prog this-is-one-argument
Will all be contained in a single variable: argv[1]
If you compile this as echo.exe it will put to stdout any thing typed into stdin:
int main(int argc, char **argv)
{
if(argv != 2) return 0;
fputs(argv[1], stdout);
return(0);
}
Usage: echo "this will be echoed onto stdout"<return>
Usage: abc000<return>
Usage: this-is-one-argument<return>
I have recently started learning C language so I don't much about the functions of C.
Recently I saw a program written in C on Internet article. It was like this:-
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i = 0;
int j = 0;
char ch;
ch = getopt(argc, argv, "n:");
if(ch == 'n')
{
j = atoi(optarg);
}
while(j--)
{
printf("%i\n",j);
}
return 0;
}
Can anyone tell what is the actual purpose of argc in getopt() function? Does it uses argc as for upto where it should read options?
In my observation argc is there to write simple code and the argv NULL to write defensive code.
argv and argc has been in main's signature since the very beginning of C, so has the NULL at the end of the argv list. I've looked at many C programs since then and almost none of them depend on that NULL. Rather they depend on argc to control the array depth as it is simpler and more reliable. However, the defensive programmer will also look for that NULL as well as using argc and getopt() should use argc to complain if it's called too many times.
Also, I've seen code that plays games to reuse getopt() to parse secondary "command lines" for commands given to the application. Not all of those put a NULL on the end of the list (mine did, though).
The C standard does guarantee that argv[argc] is a NULL pointer:
C Standard, §5.1.2.2.1.2:
If they are declared, the parameters to the main function shall obey the
following constraints:
...
— argv[argc] shall be a null pointer.
Technically, all you (and the function getopt) really need is argv - something like this will process all arguments:
int i;
for(i = 0; argv[i]; i++)
{
puts(argv[i]);
}
However, there is nothing stopping you (or the author of getopt) from using argc as a loop guard instead. This is equally valid:
int i;
for(i = 0; i < argc; i++)
{
puts(argv[i]);
}
So, if the function says it requires argc to be passed, then pass argc to it, because it probably uses it to form that type of loop.
I'm just trying to check the commandline arguments and see if it works in the command line. It works fine if I execute './a.out hello' but when I do './a.out' I get the error.
#include <stdio.h>
int main(int argc, char * argv[]){
printf("Test");
printf("\n%s",argv[0]);
printf("\n%s",argv[1]);
return 0;
}
The reason why I'm doing this is because I'm going to take that string and compare it later on. I don't understand why something this simple is causing an error.
You're not checking the length of argv before dereferencing the second argument. If argv only has one element argv[1] is a null reference, which causes your fault.
With C everything needs to be done carefully. To answer your question, yes, an if statement is the right approach if you want to handle the command line yourself. The argc parameter to main() is provided for exactly this purpose.
#include <stdio.h>
int main(int argc, char * argv[]){
printf("Test");
if (argc > 0) {
printf("\n%s", argv[0]);
if (argc > 1) {
printf("\n%s", argv[1]);
}
}
return 0;
}
Theoretically argv[0] is always populated with the application name so the first if is redundant but with C caution is your friend.
However, don't take this path. For everything except trivial applications you should use a parameter parsing library such as http://www.gnu.org/software/libc/manual/html_node/Getopt.html, check Christian's excellent answer here https://stackoverflow.com/a/24479532/2381157 for more options.
So I have a program which takes a command line argument from the user and uses atoi to convert it to a number. It all works fine until the number that is passed from the command line is more than 2048.
Here is the simple program:
int no_of_elements_per_thread = 0;
int main(int argc, char* argv[])
{
int status;
void* thread_arg;
void* res;
int i = 0;
//initialize
no_of_elements_per_thread = atoi(argv[1]);
return 0;
}
When I run the program for different values the output is as follows:
[adeb1][open-19][~/pre2] ./pre2 2098
Segmentation fault
with smaller values:
[adeb1][open-19][~/pre2] ./pre2 210
[adeb1][open-19][~/pre2]
Interestingly if I try to do a printf with %s without doing atoi I still get segmentation fault as well with argv[1]. So it seems argv[1] is giving problem with values higher than 2048.
I am using gcc in linux if that matters.
Where is your declaration of atoi? Without #include <stdlib.h>, I would assume there is none.
You may also want to ensure argc > 1 before using argv[1].
I've built a C application, and when I build it, it shows no errors, but when I run it, it gives me the error "Segmentation Fault: 11".
If it helps, here is the code I am using:
#include <stdio.h>
int main(char *argv[]) {
printf("The project path is: ./Projects/%c", argv[1]);
return 0;
}
The correct main prototyped syntax is
int main(int argc, char *argv[]) { ... }
Also %c conversion specification in printf prints a character, to print a string use %s.
You have a number of problems:
The signature for main is an argument count followed by an array of C strings.
You should always check the count before using the array.
The array is of strings so you need %s to print them.
This should work:
#include <stdio.h>
int main(int argc, char *argv[]) {
if (argc < 2)
fprintf (stderr, "Wrong number of arguments\n");
else
printf ("The project path is: ./Projects/%s\n", argv[1]);
return 0;
}
Change the signature to int main(int, char*[]);
What arguments are you passing to the process? If you're not passing any argv[1] is out of range
In addition to the other suggestions, you may need to revisit your printf format. %c is used to print a single character, and argv[1] is char *. Either use argv[1][0] or some such, or use the string format specifier, %s.
First, change your main to:
int main(int argc, char *argv[])
Second, you have a mismatch between what you're passing to printf, and what you've told it you're going to pass. argv[1] is a pointer to characters, not a character. You need/want to use the %s conversion to print it out:
printf("The project path is: ./Projects/%s", argv[1]);
In this specific case, it's not really mandatory to check for enough arguments, because even if you don't pass any command line arguments, argv will contain at least argv[0] followed by a null pointer. As such, using argv[1] is safe, but if you haven't passed a command line argument, may print as something like (null).
Nonetheless, you generally want to check the value of argc before using argv. In this case, you can get away with it, but only more or less by accident. Trying to use argv[2] the same way could give undefined behavior.