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.
Related
This question already has answers here:
What does int argc, char *argv[] mean?
(12 answers)
Closed 5 years ago.
in my C script my input is printing out gibberish and im not sure why
heres more or less what i have on it
int main (int arg, char argv[])
{
printf(argv);
}
this prints out giberish?
The following should yield the results you are looking for
#include <stdio.h>
int main(int argc, char **argv)
{
// Check if there is at least 2 arguments. First argument is the executable name.
if(argc > 1)
{
// Print out a string, followed by a new-line character.
printf("%s\n", argv[1]);
}
// Exit successfully
return 0;
}
Edit: After looking at your code here and some of the things I recommend to change:
The signature of your main function to int main(int argc, char **argv). Here argc is the argument count, and argv are the argument values. argv is a double-pointer. If we consider char* to be a string (sequence of characters in memory terminated by a null-character, or 0), then argv is a pointer to argc-many strings.
Secondly, to check the first program argument, consider making sure that there is in-fact an argument there. if(argc > 1) will make sure there is at least 1 argument to the program (the 0-index argument to a program is the executable path).
When you want to actually check the value of the first argument, de-reference argv to get a "string" with argv[1] //The first argument. Then you can de-reference this string to get the first character
if ( *(argv[1]) == 'f' )
{
....
}
If you want to check for a full string, rather than just a single character, consider using a function such as strcmp defined in <string.h>.
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.
I am writing a program that takes a command line argument and user input, and calculates the difference between the two characters (cryptography). I would like to pass my argument into a variable within the program, but am unable to do so.
#include <stdio.h>
int main(int argc, char** argv) {
char plain[2];
char cipher[2]; /*locations of plain and cipher text*/
char *ppoint; /*pointers to plain and cipher*/
char *cpoint;
scanf("%s",plain);
*ppoint=plain[0]; /* ppoint points to 1st character in plain*/
cipher=argv[1]; /* cpoint points to first argument character*/
*cpoint=cipher[1];
printf("%s %d \n",ppoint,plain);
printf("%s %d \n",cpoint,cipher);
return 0;
}
For line 14, I am met with a compiler error ,
(cipher=argv[1];) " Incompatible types in assignment "
I have been experimenting with many methods such as type casting but I can not get anything to work.
I would like the two last lines of my program to output the actual character and their respective ASCII values. Please help me past this block!
UPDATE:
#include <stdio.h>
#include <string.h>
int main(int argc, char** argv) {
char plain;
char *cipher; /*locations of plain and cipher text*/
int *ppoint; /*pointers to plain and cipher*/
int *cpoint;
scanf("%s",plain);
*ppoint=(int) plain; /* ppoint points to 1st character in plain*/
cipher=argv[1]; /* cpoint points to first argument character*/
*cpoint=(int) cipher;
printf("%s %d \n",plain);
printf("%s %d \n",cipher);
return 0;
}
I used type casting to fix any compiler errors. However upon running the program and in putting a value for 'plain', I am met with a segmentation fault. I have looked long and hard but cannot see where this memory error is occurring. Please help.
You are attempting to assign a char pointer to a char array, which is not allowed. You'll need to copy the argument some other way. For example, you could use strcpy:
strcpy(cipher,argv[1]);
Alternatively, you could make cipher be a char pointer instead if you never modify it.
const char *cipher;
...
cipher = argv[1];
try using,
ppoint=(int) plain; /* ppoint points to 1st character in plain*/
Without the '*', as you cannot use the de-referencing operator on the pointer variable as the pointer doesn't point to any location yet.
I tried to add an argument to main by scanf. But it didn't work. The following is my program. My question is: what's wrong with this program? And is it possible to add an argument to main by scanf() instead of in the command line?
#include <stdio.h>
#include <errno.h>
int main(int argc, char* argv[]){
/*check if there is no argument, that is, argc!=2*/
if(argc != 2){
puts("Please enter an argument: ");
scanf("%s", &argv[1]);
printf("\nYou've entered argument: %s\n", argv[1]);
return 1;
}
printf("\nYou've entered argument: %s\n", argv[1]);
return 0;
}
Yes, code can effectively add arguments.
"The parameters argc and argv and the strings pointed to by the argv array shall be modifiable by the program, and retain their last-stored values between program startup and program termination." C11dr ยง5.1.2.2.1 2
So this allows code to change argc and argv and change argv[0][0] (if argc > 0) - but wait, there's more...
Can code change the original elements of argv[], like argv[1], etc? That is an open question still hanging in SO here. So let us avoid that.
The way to change the contents of argv[] is to first create an alternate set argv_alt[] array and then assign argv_alt --> argv.
#include <stdio.h>
int main(int argc, char *argv[]) {
// Assume argc == 1
printf("%d '%s'\n", argc, argv[0]);
char a[3][10] = { "abc", "def", "fgh" };
char *argv_alt[] = { a[0], a[1], a[2], NULL };
argc = 3;
argv = argv_alt;
printf("%d '%s' '%s' '%s'\n", argc, argv[0], argv[1], argv[2]);
return 0;
}
Argv is allocated by the system when the user types in her arguments. If there wasn't arguments you cannot use the position 1 on that array. Although, as pointed out on the comments, you shouldn't do the way you are willing to, you could scanf arguments if you declare your own local variable.
The %s specifier in scanf expects that you pass in a pointer which points to space that has already been allocated and is big enough to hold whatever will be read.
Instead you pass in a pointer which points to an area where another pointer is stored. This causes undefined behaviour because the pointer you pass in has the wrong type.
It's not possible to extend the length of the argv array. In fact, writing to argv[n] probably causes undefined behaviour anyway.
Instead you should just read into a variable inside main.
I'm working on a C program with some system calls and I'm saving variables as follows:
int inhandle,outhandle,bytes,read_while_writing_nhandle;
char source[128],target[128];
Right now my program prompts the user with
printf("enter source file name\n");
scanf("%s",source);
How can I change it so a user can just type "run sourceName targetName"
aka, storing them as argv[1] and argv[2]?
I also use the inputs (target and source)
in handles like:
inhandle=open(source,O_RDONLY);
My main issue is conversion since I'm storing target and source as char. I could use something like strcpy.
It would just be very much appreciated if someone could help me out with it. Hope this was clear. Thank you.
*********EDIT: I apologize, I probably wasn't clear enough...
I tried doing the int main(int argc, char *argv[]) and then including:
if(argc==3)
{ source = argv[1]; target = argv[2]; }
else{ printf("Syntax error.\n");
return -1;
But I'd get conversion errors since I can't store them that way. And if I do store them as pointers (like *target=argv[2]) I'm worried they won't work when I call the handles.. (ex: outhandle=open(target...) works but I can't do open(*target..)
Use int main(int argc, char **argv);
And then assign source to argv[1] and target to argv[2]
Change to:
if(argc==3)
{
strcpy(source, argv[1]);
strcpy(target, argv[2]);
}
Also, read up on the dangers of strcpy, and consider strncpy.
But using strcpy will get you started at least...