I am creating simple calculator. I give arguments to be calculated as command line arguments.
How do check if user gave no arguments at all?
I Tried this, but i get segmentation fault:
int main(int argc, char* argv[]){
if(argc == 0){
printf("No arguments were given");
return 0;
}
argc is the count of the program name and its arguments.
When argc == 1, there is only the program name and no additional arguments.
It is possible for argc == 0 as that implies even the program name is not passed in.
Test against 1
if (argc <= 1) {
printf("No arguments were given.\n");
}
i get segmentation fault:
This is certainly due to unposted parts of OP's code.
Related
segmentation problem occur while debugging the code how can i resolve the issue
debugging problem can't find a solution please help
#include<stdio.h>
#include<cs50.h>
#include<ctype.h>
#include<string.h>
int main(int argc,string argv[])
{
int len = strlen(argv[1]);
if(argc != 2 )
{
printf("Usage:./substitution key\n");
return 1;
}
}
Check if argv is valid before accessing it:
int len = strlen(argv[1]);
if(argc != 2 )
If argc != 2 evaluates to true, then argv[1] would be a NULL pointer (assuming argc is 1).
Check if the arguments are valid before you try to access them, else your program could dereference a NULL pointer and exhibit undefined behaviour.
if (argc != 2) {
/* print usage message here.. */
return EXIT_FAILURE;
}
strlen() returns a size_t:
Note that strlen() returns a size_t, not an int. Do not mismatch numeric types.
Error messages should go to stderr:
Error messages deserve to be printed to stderr, not stdout.
fprintf(stderr, "Usage:./substitution\n
Or as formatted output is not required here, simply:
fputs ("Usage:./substitution\n", stderr);
See also: Why use stderr when printf works fine?
Suppose we are given a task to write a function that add 2 numbers.
#include <stdio.h>
int main(int argc, char ** av) {
int a = atoi(av[1]);
int b = atoi(av[2]);
add_and_print(a, b)
return 0;
}
It works fine untill I pass following code:
./a.out
Just passing empty strings. Then it writes the following:
1495 segmentation fault (core dumped)
Could you please explain what is the problem and how do I deal with it ?
argc contains the number of arguments provided to the program, and if you don't check it then you might get a segfault trying to read from argv. You can display an error message and exit if there aren't enough arguments:
if (argc < 3) {
puts("Please provide 2 numbers as command line arguments.");
return 1;
}
How do I deal with segfault
The segfault happens because of a bug in your code.
So, you prevent it happening in the first place, by not writing buggy code.
In general though, the segfault makes it easy to find out exactly what bug triggered it: just run your program under the debugger, and it will stop exactly where the segfault occurs.
Could you please explain what is the problem
In this code:
int a = atoi(av[1]);
the expression av[1] is only legal if there are at least two elements in array av (since we start indexing at zero). If there is only one element, this code attempts to read beyond the end of the array.
Since the array is based on the command-line arguments, you must check it. You need to do this for all inputs from users, files, even other parts of your own code. Don't just assume the user did what you expected (or the file contained what you expected, or the caller passed the right values). This is a bug.
if (argc >= 2) {
// now it is safe to refer to av[1]
a = atoi(av[1]);
}
You have to do something similar for av[2], for the same reason.
A common solution might be instead
int main(int argc, char **argv) {
if (argc < 3) {
printf("Syntax: %s a b\n"
"\n"
"Two integer arguments are required.", argv[0]);
return -1;
}
int a = atoi(argv[1]);
int b = atoi(argv[2]);
add_and_print(a, b)
}
I'm just assuming that argc is at least 1, and that argv[0] is the name of the program. You can check this too if you want perfectly portable code.
Note that you might also want to check whether the arguments are really integers.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I am writing a program to print the last n characters of a .txt file. I wish to add the ability to run the program from the command line with a -n argument to input the amount of characters to print.
I have tried declaring int main(int argc, char* argv[]) but that seems to accept any amount of arguments and I only need the one -n argument.
To do that, you can use strncmp and strtol:
int main(int argc, char* argv[])
{
int n = 0;
if(argc > 1)
{
if(!strncmp(argv[1], "-n", 2))
{
n = strtoll(argv[1]+2, NULL, 10);
}
}
if(n == 0) /* fail */;
/* do stuff */
}
This checks if argv has more than just one argument (the name of the program) and then checks for -n, and, if it finds it, converts the number directly after -n to an integer (i.e. -n3 is converted to three).
If you want to accept one argument only and fail otherwise, change argc > 1 to argc == 2.
and I only need the one -n argument. You will need at least 3 arguments if you require the -n argument. (meaning argc - argument count will be 3.)
... This is assuming the -n argument will be followed by an integer value to indicate how many characters are to be read. If the number of characters to be read from your file is 3, it would be called on the command line for example as:
programName.exe -n 3
This results in the arguments of main(int argc, char* argv[]) being populated as:
argc == 3
argv[] == {"programName.exe", "-n", "3"}
So yes, the C main signature int main(int argc, char* argv[]) will accommodate 1 to many arguments, but that does not exclude it from being used to create a program that will accept only 2 arguments. (The first argument listed by convention is always the executable name of the program the code is compiled into.)
If you would like to have only the one additional argument (which would result in a count of 2 actual arguments), skip including the '-n' and define your Usage as requiring a singe positive digit following the program name:
programName.exe 3
Then code it like this:
int main(int argc, char *argv[])
{
char *dummy;
int val;
if(argc != 2)
{
printf("Usage: prog.exe <n> where <n> is a positive integer value.\nProgram will now exit");
return 0;
}
// Resolve value of 2nd argument:
val = strtol(argv[1], &dummy, 10);
if (dummy == argv[1] || ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE))
{
//handle error
}
//use val to read desired content from file
...
return 0;
}
This question already has answers here:
How to properly compare command-line arguments?
(4 answers)
Closed 4 years ago.
So I have to write a program that contains two possible options depending on what the user chooses by entering either -i or -w. I'm very new to command line arguments in general and I have no idea how to do this. So far I have:
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc == -'i') {
puts("Test 1");
}
else if(argc == -'w') {
puts("Test 2");
}
return 0;
}
It doesn't print anything...
Any explanation is greatly appreciated. I'm just trying to understand the logic behind this.
First of all, you are comparing oranges with appels. argc stores the number of
arguments. Second, even if you used argv[1], the comparison would be still
wrong, because it would be comparing pointers, not the contents. Note that in C
a string is a sequence of characters that terminates to '\0'-terminating byte.
A char* variable only points to the start of that sequence. The == operator
checks for equality of values, in case of pointers (and string literals), it
compares whether both pointers point to the same location.
When you want to compare strings, you have to compare the strings themselves,
that means you have to compare the contents where the pointers are pointing to.
For strings you have to use the strcmp function like this:
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc != 2)
{
fprintf(stderr, "usage: %s option\n", argv[0]);
return 1;
}
if(strcmp(argv[1], "-i") == 0)
puts("Test 1");
else if(strcmp(argv[1], "-w") == 0)
puts("Test 2");
else {
fprintf(stderr, "Invalid option '%s'\n", argv[1]);
return 1;
}
return 0;
}
Note that it is important to check first that you have enough command line
arguments (the first if of my code). If the user didn't pass any argument,
argc will be 1 and argv[1] will point to NULL, which would yield undefined
behaviour if it is passed to strcmp. That's why I only do strcmp when I'm
100% sure that argv[1] is not NULL.
Also if you are coding for a POSIX system (linux, mac, etc), then I recommend using
getopt for parsing of the command line arguments.
You have to check argv[i] where i is the array number of the command line argument being put in, argv[0] would be the file name called upon and after that argv[1] would be the first statement, argv[2] the next and so on
argc means "argument count". meaning the number of arguments
argv is a 2-dimensional array. Strings are 1-dimensional character arrays in C. The second dimension comes from you having multiple String.
So if you want the first String argument, you would access it as follows:
argv[0]
You are also attempting to compare strings, which are more than 1 character long. You should use strcmp to compare strings in C. See How do I properly compare strings?
and if you want to compare equality, you would not use ==, == is for basic data types such as int or char.
argc represents the number of parameters that were passed in at the command line including the program name itself.
In c, a character, e.g., 'i' is an 8-bit number representing the ASCII code of the letter i. So your conditional statement if(argc == -'i') is actually checking whether -105 (105 is the ascii value of the letter i) is the number of arguments that was passed to your program.
To check whether the arguments passed in are "-i" or "-w" you need to perform string comparison, using the c library functions or your own algorithm, and you need to be comparing those strings to argv[i] (where i is the position of the parameter you're checking in the program invocation)
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("The name of the program is %s\n", argv[0]);
if( strcmp(argv[1], "-i") == 0 ) { puts("Test 1"); }
if( strcmp(argv[1], "-w") == 0 ) { puts("Test 2"); }
return 0;
}
This is my main function code
os2.c
#include <stdio.h>
int main( int argc, char *argv[]){
int item;
item = argc;
printf("%d", item);
return 0;
}
I run the following command line in Ubuntu's terminal
gcc -o test os2.c
./test 5
The result printed is equal to 2 instead of 5, What's wrong with my code?
First, your question is not just for Ubuntu/Linux.
It works in Windows and Macintosh too including every OS using the terminal.
argc = argument count: the number of argument that are passed to a program
argv = argument vector: passed arguments
argc is an int that count the arguments of your command line.
I run the following command line in Ubuntu's terminal: gcc -o test os2.c
./test 5
Here your arguments are
argv[0] == ./test
argv[1] == 5
So we conclude that:
argc is 2 based on the number of arguments above.
argv contains the arguments that we've passed to the program.
This is an example of how you use arguments in the right way:
source.c
#include <stdio.h>
int main(int argc, char **argv){
for(int i = 0;i < argc;i++)
printf("arg %d : %s\n",i,argv[i]);
return 0;
}
Command Line
gcc -o test source.c
./test this is a test
Output
arg 0 : ./test
arg 1 : this
arg 2 : is
arg 3 : a
arg 4 : test
But anyways, I recommend to never use the first argument; It'd be a gap in your software cause it can be hacked easily. There're many ways to do whatever you want in C.
Now; You should know what you've to do if you want to get the value 5 instead of counting the number of arguments that you've passed to your application which in the OP case were 2.
argc means the number of argument that are passed to the program. not printed which value you have passed.
Use argv[1] to print value of 5.
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc >= 2)
printf("%d\n", atoi(argv[1]));
return(0);
}
argc (argument count) and argv (argument vector) are how command line arguments are passed to main() in C and C++.
argc is number of arguments passed to program (number of strings pointed to by argv), which is correct in your case. First string is program name, second string is "5" (so you have to convert "5" to int).
This might be a useful reading for you.
If you want to convert second argument to int try this
if (argc < 2)
{
return -1;
}
int item = atoi(argv[1]);
atoi may lead to undefined behavior so you should use strtol instead.
Or you may loop through all arguments
for(int i = 0; i < argc; i++)
{
// argv[i] is the argument at index i
// You may print them
printf("%s", argv[i]);
// Convert them, ...
}
Nothing wrong with code. You are passing two arguments ./test and 5. So it shows 2. It is the number of arguments passed to the program.
argc : argument count.
To get the argument passed you can do this.
printf("%s",argv[1]);
In general you check it like this:
if(argc!=2)
{
printf("Usage: ./program-name argument\n");
return EXIT_FAILURE; // failure-considering you are writing this in main.
}
// do your work here.
But in argv[1] you will get the char string. To get an integer out of it, you have to convert it using something like atoi or your custom conversion function. Also you can use strtol() which is useful in conversion from string to long.
1. In case of main return EXIT_FAILURE works but not in other functions but exit(EXIT_FAILURE) works in all the functions
argc is the count of arguments, which is 2 here. If you intend to print 5, you need to print argv[1] (or if you always want the last argument, argv[argc-1]) instead.