Command line arguments in main - c

I've written a code that sums up integers brought in from the command line:
#include <stdio.h>
int main(int argc, int* argv[]) {
int i, s=0;
for (i=1;i<argc;i++)
s=s + *argv[i];
printf("Sum: %d\n", s);
return 0;
}
The best part is, it passes the gcc compiling process, but when I actually run it and insert the numbers, the result seems I somehow breached the range of int.

It seems that you are compiling your code in C89 mode in which s is taken as int by default by compiler. s is uninitialized therefore nothing good could be expected. If fact it will invoke undefined behavior.
Note that argv[i] is of char * type (change your main signature) and you need to convert it to int before adding it to s.

The 2nd argument of main should be either of type char** or of type char*[] and not int*[]. So, *argv[i] is of type char. Instead of getting each character, you can get each string(argv[i] which is of type char*) and then extract the number from it and assign it to a variable, say num. This can be done by using the sscanf function:
#include <stdio.h>
int main(int argc, char* argv[]) { //int changed to char here
int i, s=0,num;
for (i=1;i<argc;i++)
if(sscanf(argv[i],"%d",&num)) //if extraction was successful
s=s + num;
printf("Sum: %d\n", s);
return 0;
}

Assuming you have s initialized properly as shown below.
Along with this the prototype of your main() should be as shown below inorder to get the command line arguments.
int main(int argc, char **argv)
{
int s =0;
// Check for argc matches the required number of arguments */
for(i=1;i<argc;i++)
s=s + atoi(argv[i]); /* Use atoi() to convert your string to integer strtol() can also be used */
printf("%d\n",s);
return 0;
}
PS: Using uninitialized variables lead to undefined behvaior

Related

Return unsigned char array to main function

Background: My original main() is:
int main(int argc, char *argv[])
{
unsigned char output[16] = {0x00}; // copied from code
// .... (some steps to calculate output[i])
for (i = 0; i < 16; i++)
{
printf("%02X ", output[i]); // output[i] is an array of 16-byte hex values
}
return 0;
}
The original program (e.g., calculate.c) is run by command line:
./calculate $(echo "this_is_input"|xxd -p)
Now I want to modify main() as a call function only, e.g., named run(). And write a new main() to call run() function.
The input (equivalent to above command line) is hardcoded in new main(). main() will pass the input value to run() function (instead of using above command line).
run(int argc, char *argv[])
{
....
return output[i];
}
then run() returns the same output[i] to main()
int main()
{
input_char = **equivalent to $(echo "this_is_input"|xxd -p)** // how to define?
unsigned char returned_output[16] = {0x00};
returned_output = run(X, input_char);
print(returned_output);
}
Question:
How to present the hex dump value of $(echo "this_is_input"|xxd -p)** in the main()?
How to modify run() and main() in order to return unsigned char array to main()?
How to present the hex dump value of $(echo "this_is_input"|xxd -p)** in the main()?
You can represent it as an array of characters, or for example an array of arrays of characters - tokenised by whitespace. Latter is the representation that the command line arguments are already in argv.
How to modify run() and main() in order to return unsigned char array to main()?
You must declare the return type of the function. It is not possible to return an array directly in C, and it is undesirable to copy arrays around. A typical solution is to let the caller (main) create the array, and let the called function modify the content of the array:
void run(int argc, char *argv[], unsigned char output[16])
main has a problem. It attempts to assign an array. Arrays are not assignable. Given that arrays cannot be returned from functions either, this makes little sense.
This is how to call run that I've suggested:
unsigned char output[16] = {0x00};
run(argc, argv, output);

Can't accept multiple command line arguments and assign to variable

I am learning C and I am not used to pointers and the way C handles strings. I am trying to create a program that accepts multiple command line arguments and assigns them to variables so that I can later use them. I can get the program to accept the first argument and assign it as a int. But when I try to accept the second argument I get a SEGMENTATION FAULT. I have tried testing by removing the second variable (service) and then assigning port to argv[2] and it doesn't work. It is something about accepting the second argument that the compiler does not like but I am not able to figure it out.
#include <stdio.h>
int main(int argc, char *argv[]) {
int port = atoi(argv[1]);
char service = argv[2];
return 0;
}
When you write char service = argv[2];, you are assigning a char pointer to a char. You know argv is a char pointer array, because you define it as char *argv[]. Fix by just adding char *service = argv[2];
So your rewritten code could look like this:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc < 3) {
printf("Requires more arguments");
return 1;
}
int port = atoi(argv[1]);
char *service = argv[2];
printf("%s", service); //From edit
return 0;
}
You may want to add a check for the value of argc (i.e. argc >= 3), since it will seg fault if there aren't three arguments.
Edit (response to comment):
To print the service, use:
printf("%s", service);
The %s specifies you will print a string of characters (char *) and you simply use service, because you need to specify the pointer.
Edit 2:
If you don't add #include <stdlib.h>, you will receive something along the lines of "warning: implicit declaration of 'atoi' is invalid in C99", which may also produce an error depending on your compiler settings.

(windows) DevC++ GCC compiler hangs up or prints infinite characters

I am trying to write some C code, and while running the following, my compiler terminates abruptly, after printing 'A'. Why?
//report expected thing
void Expected(char *s){
int i=0;
int n = sizeof(s)/sizeof(s[0]);
while (i< n)
printf ("%c", s[i]);
printf(" expected.\n");
}
int main(int argc, char *argv){
printf("%c",65); //after this compiler hangs and asks for exit abnormally
char *Arr ={'a'};
Expected(Arr);
return 0;
}
Also, if I put
char *Arr ={"a"}; //note the double quotes
then it starts printing out infinite number of 'a's. Why should this happen?
int n = sizeof(s)/sizeof(s[0]);
is not how to get the length of the array of which the pointer passed as the argument points at the first element.
Pass the size of the array if you want to let your function know that.
char *Arr ={'a'};
Is not good because 'a' is a integer and you converted it to a pointer, then the result has too little chance to be a valid pointer.
char *Arr ={"a"};
is OK because it is a valid pointer, but it will be infinite loop because i is not updated in the while loop.
The type of main() function is implementation-defined. You should use standard type unless you have some reason to use special main().
Your code should be like this:
#include <stdio.h>
//report expected thing
void Expected(const char *s, size_t n){ /* add const because the contents of array won't be modified */
size_t i=0; /* use size_t to match type of n */
while (i < n)
printf ("%c", s[i++]); /* update i */
printf(" expected.\n");
}
int main(void){ /* use standard main(). int main(int argc, char **argv) is the another standard type */
printf("%c",65); //after this compiler hangs and asks for exit abnormally
char Arr[] ={'a'}; /* declare an array instead of a pointer */
Expected(Arr, sizeof(Arr)/sizeof(Arr[0]));
return 0;
}
Finally, if it is really not your produced executable but your compiler that is crashing, throw the broken compiler away and get a new one.

how string (command line) are stored in char**argv and int *argv?

First snippet:
#include<stdio.h>
int main(int argc, char **argv)
{
int i;
for(i=1; i<argc; i++)
printf("%s\n", argv[i]);
return 0;
}
load time input :
./a.out devang samir
output:
devang
samir
Second snippet:
#include<stdio.h>
int main(int argc, int *argv)
{
int i;
for(i=1; i<argc; i++)
printf("%s\n", argv[i]);
return 0;
}
load time input :
./a.out devang samir
output:
devang
samir
in both case, i got output same, but why?
in first case how the strings (command line ) are stored in char** argv ?
in second case how the string (command line ) are stored in int * argv...?
The C11 standard specifies the function signature for main() in chapter §5.1.2.2.1 as
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names may be
used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;[...]
and regarding the constrains,
If the value of argc is greater than zero, the array members argv[0] through
argv[argc-1] inclusive shall contain pointers to strings,[...]
Then, in your second case,
int main(int argc, int *argv)
char* and int ( for argv[n], in general) are being different types altogether (i.e, not compatible type), your second program invokes undefined behavior.
To elaborate, in case of the functions without having a prototype, the parameters passed to the function while calling should exactly match the type of expected arguments.
Quoting the standard, chapter §6.5.2.2
[...] If the function is defined with a type that does not include a prototype, and the types of
the arguments after promotion are not compatible with those of the parameters after
promotion, the behavior is undefined.

C I cant printf an integer, which was passed as a argument in command line

I'm trying to printf an integer that was passed by command line but the console print a long random values.
I put this into RUN "C:\Users\pc\Documents\Visual Studio 2013\Projects\Lab3\Debug\Lab3.exe randomString 4"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char *argv[]){
printf("%s\n", argv[0]); // Working
printf("%s\n", (argv[1])); // working
printf("%d\n", (int)(argv[2])); // NOT Working
printf("%d\n", argc); // Working
system("pause");
return 0;
}
You can't just "cast" a char* pointer to an int and expect it to be magically converted. That is just printing the address of the first element of the array. You need to convert it to an int with a runtime function such as atoi(argv[2]) See function details here
The argv[2] variable is a string pointer (char* to be precise). So casting it to int will just give you the numerical value of this pointer (or part of it, depending on the size of the addresses on your system). And this is exactly your "random long number" that you are seeing. In order to convert the string to a number you can use functions like atoi.

Resources