Using command line arguments in C - c

I have the following code where I try to access the command line arguments but I am having trouble doing so.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv) {
int fd = open("drawing.ppm", O_RDWR | O_CREAT | O_APPEND, 0700);
char colour[] = "0 0 0 ";
if(argv[1] == "red") {
char colour[] = "255 0 0 ";
}
printf("%s\n", &argv[1]);
int date = write(fd, colour, sizeof(colour));
close(fd);
}
When I run the code, the terminal displays 1▒ which is some weird unexpected symbol. Can someone please tell me why this isn't working?

A few things.
First your signature for main() is wrong it should be
int main(int argc, char *argv[])
Notice how argv is an array (pointer) of strings not chars.
Second you don't check to see if there were any args passed.
Something like
if (argc > 2)
Third your printout is the address of argv[1] instead of argv[1]
Try (inside/after the argc check)
printf("%s\n", argv[1]);

you declare 2 times colour variable take care of that the second one is local to the if-scope.

The type of argv[1] is char* and you try to use with the operator == which is useful for string type variables. Here you are comparing two pointers, in fact, two memory addresses.
You may try to use strcmp to compare the contents of objects pointed by the pointers.

Related

How to add "int argc and char *argv[]" to my main function and impliment into my code?

I am working on creating an uppercase function. I want to implement argc and argv arguments in to my code but I don't know how to do it.
Here is my code;
Main.c:
#include <stdio.h>
#include <stdlib.h>
#include "upperc.h"
int main(int argc, char *argv[])
{
char s[] = "HellO2 world3!";
printf("%s \n", s);
printf("%s \n", uppercase(s));
return 0;
}
upper.c:
/*
Parsing the string, then making the letters to uppercase.
*/
#include <stdio.h>
#include "upperc.h"
char * uppercase(char *s) {
for(char *p = s; *p; ++p) {
if ('a' <= *p && *p <= 'z')
*p = *p & ~' ';
}
return s;
}
upper.h:
#ifndef UPPERC_H_INCLUDED
#define UPPERC_H_INCLUDED
char * uppercase(char *s);
#endif // UPPERC_H_INCLUDED
As this looks like some kind of homework, I don't give a full answer.
argc is the number of arguments including the program name that was executed. That means argc is 1 if no arguments were specified, 2 if one argument was specified etc.
Don't pass argv[1] unconditionally to your uppercase function. This would be undefined behavior if argc is 1 or even 0. (see below for details)
Depending on your requirements, you should check argc and process either only argv[1] if available, which would be the first argument, or process argv[1], argv[2] ... in a loop as necessary.
Additional details (for experts, because my original wording was not exact):
If your program is called in a normal way, the value of argc should be at least 1 and argv[0] will be the program name. The value of argv[argc] is a NULL pointer. Of course you can access the pointer value in this case, but you cannot dereference it, i.e. you cannot access a value where the pointer would be pointing to.
It is possible to call your program in a way that results in an argc value 0. In this case argv[0] will be a NULL pointer, and the array element argv[1] (and all following it) will be undefined.
See https://en.cppreference.com/w/c/language/main_function

Turning off stack protection

I was just wondering, cause I have this C code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int fillBuffer(int argc, char *argv[]) {
char bufferA[4] = "aaa";
char bufferB[4] = "bbb";
if(argc > 1)
strcpy(bufferB, argv[1]);
printf("bufferA: %s\n", bufferA);
printf("bufferB: %s\n", bufferB);
return 0;
}
int main(int argc, char *argv[]) {
fillBuffer(argc, argv);
return 0;
}
and I tried turning off the stack protection by using the: -fno-stack-protector
and when I try to run it by doing: ./program (escape key) 5f, the program outputs to:
bufferA: f
bufferB: fffff
I'm just not sure how bufferA becomes f also. Can anyone explain this to me?
The local buffer A and B are stored reverse order on your stack. So, on in memory you have 8 bytes starting buffer B then buffer A.
When you strcpy your 5 "f" to buffer B, the first 4 go into buffer B, and the last one with the end string '\0' to buffer A.
Then when you printf your buffers, buffer A contain 1 "f" and the string terminator. That's where it comes from.
Your strcpy call is unsafe, and will corrupt your stack if argv[1] contains more than 3 characters (plus one for the null termination character). Do not hit escape, just space and the 5f and you get the proper output:
scott> a.out 5f
bufferA: aaa
bufferB: 5f
When you hit escape, the shell can add additional characters to the string parameter, and because your strcpy is unsafe (does not check length) it will go beyond the end of your buffer and corrupt your stack. Your buffer is only 4 characters long, so your program will corrupt the stack if a parameter longer than 3 characters is entered.
To fix it, increase your buffer size from 4 to something more reasonable like 60, and use strncpy to ensure that you do not exceed the buffer if the parameter is too long:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_PARM_LEN 60
int fillBuffer(int argc, char *argv[]) {
char bufferA[MAX_PARM_LEN] = "aaa";
char bufferB[MAX_PARM_LEN] = "bbb";
if(argc > 1)
strncpy(bufferB, argv[1], MAX_PARM_LEN);
printf("bufferA: %s\n", bufferA);
printf("bufferB: %s\n", bufferB);
return 0;
}
int main(int argc, char *argv[]) {
fillBuffer(argc, argv);
return 0;
}
One last point: don't turn off stack protection.

Save command line argument as global variable in C

I'm trying to read in two filenames and save them as a global variable in C.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char infilename;
char outfilename;
int main(int argc, const char* argv[]){
strcopy(infilename, argv[1]);
return 0;
}
However this does not work. Can someone help me with a really simple problem like this?
You are trying to copy a string (const char *) to a character (char). You need to either declare infilename as a string:
char *infilename;
infilename = malloc(...
or make a static array:
char infilename[NUM_OF_CHARS];
Read up on c strings here.
Also choose your language, if you are really using c++ you need to start using std::string
A better way to do it.
char infilename[50];
char outfilename[50];
int main(int argc, const char* argv[]){
if(argc == 3)
{
strcpy (infilename,argv[1]);
strcpy (outfilename,argv[2]);
}
else
{
//do something else
}
return 0;
}
You need array of char and not only char. A string in C is an array of char. And you must always verify (if(argc == 3) if the user entered the quantity of argument you want, because if it's not the case your applicatin can crash.
That's not going to work.
These:
char infilename;
char outfilename;
declare a variables that store a single char, not an entire string.
You either need to make those char arrays:
char infilename[MAX_PATH];
char outfilename[MAX_PATH];
or pointers that you plan to initialize with malloced memory. You have to pick which one you mean.
P.s. there's no function called strcopy, it's strcpy.
The main problem is that you made your global variables single characters not an array of characters which is needed for a string.
Assuming you don't want to change the contents of the string then the easiest thing is to simply set a global to point to the same string rather than copying it. Because the program will end when main returns there is no worry about the parameters argv going out of scope.
Note you would have to worry about this if you create a new thread and terminate the thread running main without terminating the program.
#include <stdio.h>
#include <stdlib.h>
static char* gInFilenamePtr;
static char* gOutFilenamePtr;
int main(int argc, const char* argv[])
{
if( argc > 2 )
{
gInFilenamePtr = argv[1];
gOutFilenamePtr = argv[2];
}
return 0;
}

how to create a chaine of symbolic links in c

when i try to execute this code i "segmentation fault"appears on the screen. Can someone please tell me what the error is? thanks in advance
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char * argv[]){
int fd , i;
int count= atoi(argv[2]);
char name[50];
char nname[50];
strcpy(nname, "./lfille");
strcpy(name, argv[1]);
struct stat statbuf;
/* if((fd=open(argv[1], O_RDWR)==-1)){
fprintf(stderr, "Datei existiert nicht\n");
}else*/ if((lstat(argv[1], &statbuf)==-1)){
fprintf(stderr, "Error bei lstat\n");
}else if(!(S_ISREG(statbuf.st_mode))){
printf("%s ist nicht REG\n ", argv[1]);
exit(1);
}else{
for(i=0; i<count; i++){
printf("%s", nname);
symlink(name, nname);
sprintf(name,"%s", nname);
sprintf(nname, "./lfille%d", i);
}
}
return 0;
}
I compiled the source code with gnu gcc 4.8.2.
The program worked fine for me. I think you are only passing one argument to the program instead of two. This is why. I suggest what Weather Vane said in his answer.
The parameter *argv[] is an array of string pointers, with argc informing the length of this array.
The first element argv[0] points to a string holding the program name. If there were any runtime arguments supplied when the program is run, a string pointer is supplied for each one, with the appropriate value in argc to tell you how many elements of the string pointer array have been supplied. If there were no program arguments supplied, *argv[] array will have a length of 1.
If you try to access the arguments that should have been given, you will be indexing beyond the length of the array *argv[] which leads to undefined behaviour. You will be dereferencing a pointer which has an essentially random value. This might be benign, or it might lead to the segmentation fault due to trying to access memory you are not allowed.
I suggest any program which takes (say 2) user arguments at run time have checking code similar to this:
if (argc < 3) {
printf ("Syntax should be: %s filename links\n", argv[0]);
exit (1);
}

How to receive a arg from command line in C

I want to write a program to receive a argument from command line. It's like a kind of atof().
There my program goes:
9 char s[] = "3.1415e-4";
10 if (argc == 1) {
11 printf("%e\n",atof(s));
12 }
13 else if (argc == 2) {
14 //strcpy(s, argv[1]);
15 printf("%e\n",atof(argv[1]));
16 }
1.should I just use argv[1] for the string to pass to my atof(), or, put it into s[]?
2.If I'd better put it in s[], is there some build-in function to do this "put" work? maybe some function like strcpy()??
thanks.
I personally would do it this way:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
const char defaultStr[]="3.1415e-4";
const char *arg = NULL;
if(argc <= 1)
{
arg = defaultStr;
}
else
{
arg = argv[1];
}
printf("%e\n", atof(arg));
return 0;
}
There is no need for put it into s. Just use argv[1].
Having said this, is you are putting it into s anyway (which is not that bad) make sure you change your code to:
char s[20];
strcpy(s, argv[1]);
Using strcpy with a constant char array is not a good idea.
You can simply pass it as argv[1], no need to copy it. Should you want to copy it, you need to ensure that s can actually hold the full string contained in argv[1], and allocate a bigger array if not... so it is messier.

Resources