How to sum all command line arguments in C?

I have a task. The program should print the sum of all the command line arguments in C. I tried this code, which it compiles, but throwing an error after the arguments passed in the console. Below is the code.

/* Printing sum of all command line arguments*/ #include <stdio.h> int main(int argc, char *argv[]) { int sum=0,counter; for(counter=1;counter<=argc;counter++) { sum = atoi(sum) + atoi(argv[counter]); } printf("Sum of %d command line arguments is: %d\n", argc, sum); } 

After compilation, it shows the error Segmentation error (core dumped) . Your experience can solve my problem.

Below is my edited code:

 /* Printing sum of all command line arguments*/ #include <stdio.h> #include <stdlib.h> // Added this library file int main(int argc, char *argv[]) { int sum=0, counter; for(counter=1; counter<argc; counter++) // Changed the arthematic condition { sum = sum + atoi(argv[counter]); //Removed the atoi from sum variable } printf("Sum of %d command line arguments is: %d\n", argc, sum); } 
+7
c command-line-arguments syntax-error atoi
source share
5 answers

Since you iterate to counter == argc , you point a NULL pointer to atoi() , it's simple, just rely on the fact that the argv array has a NULL watchdog timer and does this

 /* Printing sum of all command line arguments*/ #include <stdlib.h> /* For `atoi()' */ #include <stdio.h> /* For `printf()' */ int main(int argc, char *argv[]) { int sum; sum = 0; for (int counter = 1; argv[counter] != NULL; ++counter) { sum += atoi(argv[counter]); } printf("Sum of %d command line arguments is: %d\n", argc, sum); } 

Note that atoi(sum) is undefined because sum is int and is not a valid pointer. Until atoi() tries to dereference it.

Finally, enable stdlib.h for atoi() . I know that you did not enable it because I have warnings for my compiler, and it warned me that atoi() implicitly defined. This may work, but only because the undefined behavior is UNDEFINED.

Also note that there is no way to find out if the passed argument is integer, since atoi() cannot perform error checking. Instead, you can use strtol() and check if all values ​​are integers.

So ... here's how you could write a more reliable version of this program

 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int sum; sum = 0; for (int counter = 1; argv[counter] != NULL; ++counter) { char *endptr; sum += strtol(argv[counter], &endptr, 10); if (*endptr != '\0') { fprintf(stderr, "error: the `%d-th' argument `%s', is not a valid integer\n", counter, argv[counter]); return EXIT_FAILURE; } } printf("sum of %d command line arguments is: %d\n", argc, sum); return EXIT_SUCCESS; } 

EDIT . To address this comment

There is a possibility that argc == 0 , for example, if you execute a program through one of the functions exec*() . In this case, you should check before starting the loop or argv[counter] will be one element after the last, that is, outside.

+11
source share

Specifies that argv[argc] will always be a null pointer. You have too many loops and pass this null pointer to atoi , which will lead to undefined behavior.

Change the loop conditions to counter < argc .

And sum already an integer, you do not need to convert it to an integer with atoi . That atoi(sum) will also lead to undefined behavior, since the first iteration will be zero before atoi , which can also be considered as a null pointer.

+6
source share

The last argv element is defined as NULL , and the first is always the name of the program. Therefore, you can reduce your code to

 #include "stdio.h" int main(int argc, char *argv[]) { int sum = 0; for (int i = 1; argv[i]; ++i){ sum += atoi(argv[i]); } printf("Sum of %d command line arguments is: %d\n", argc, sum); } 

In your code, the behavior of atoi(sum) and what comes down to argv[argc] at the last iteration will be undefined.

+5
source share

Recursive version, just for that :)

 #include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { static int sum; if (*++argv == NULL) return !printf("sum: %d argc %d\n", sum, argc - 1); sum += atoi(*argv); return main(argc, argv); } 
-one
source share
 /* My example. Should work, though untested. */ #include <stdio.h> int main(int argc, char *argv[]) { int sum, index; // Generally considered better form to put them on separate lines. sum = 0; if(argc > 1) { for(index = 1; index < argc; index++) { sum += atoi(argv[index]); } printf("%d Command-line args\nSum = %d\n", argc, sum); } else { printf("Not enough command-line args\n"); } } 

Be sure to try your best to adhere to a specific formatting style for your code. Find style guides if you want to identify your names by name. GNU C is a good starting point . They will make your code more readable for you, easier to debug and help others understand what is going on in it.

A couple of fixes for your above code.

 /* Your code with corrections */ #include "stdio.h" int main(int argc, char *argv[]) { int sum=0,counter; // 1. Normally you want to give each variable it own line. Readability is important. // 2. Don't initialize on declaration either. Refer to my example. // 3. Always add spaces between operators and at the end of statements for better readability. for(counter=1;counter<=argc;counter++) { // 4. atoi(sum) is unneccessary as it interprets your int sum as a const char*, // which as far as I can tell should just give you back it ascii value. // It might be undefined however, so I would remove it regardless. // 5. Your segfault issue is because you iterate over the end of the array. // You try to access the [argc] value of the array (remember 0-based // indexing means a size val is always 1 greater than the greatest index). // Make 'counter<=argc' into 'counter < argc' sum = atoi(sum) + atoi(argv[counter]); } printf("Sum of %d command line arguments is: %d\n", argc, sum); } 

atoi () form documentation.

Be warned, your code will work if you enter characters or lines on the command line, but the behavior will be odd. atoi () converts char to the corresponding ASCII decimal / index value .

You can also use a null value (argv [] always ends with a NULL value in argv [argc]) to complete the iteration. I prefer to use the provided argc, though.

Hope this helps you a bit. If you don’t understand anything, I immediately drop by, comment on or search the Internet.

Hooray!

-one
source share

All Articles