C programming and argv (pointer arithmetic) - c

So, I have been working on this simple block of code. I would like it to print, when I type in "./a.out -n"
However, that is not working. I have been on stackoverflow trying to work on this, but no such luck. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
void parse_cmdline(int argc, char *argv);
int main (int argc, char *argv[]) {
parse_cmdline(argc, argv);
}
void parse_cmdline(int argc, char *argv)
{
int x,i,m,n = 0;
if (*(++argv) == 'n'){
x = 1;
printf("Output array: "); /* not being displayed*/
}
}

Just write
if (**++argv == 'n'){
And the function should be declared like
void parse_cmdline(int argc, char **argv);
Otherwise you should specify what parameter you are going tp pass to the function. For example
parse_cmdline(argc, argv[1]);
You can check what parameters are passed to the program the following way
int main (int argc, char *argv[]) {
for ( int i = 0; i < argc; i++ ) puts( argv[i] );
}

Try:
#include <stdio.h>
#include <stdlib.h>
void parse_cmdline(int argc, char *argv[]);
int main (int argc, char *argv[]) {
parse_cmdline(argc, argv);
}
void parse_cmdline(int argc, char *argv[])
{
int x,i,m,n = 0;
if (*(argv[1]) == '-' && *(++argv[1]) == 'n'){
x = 1;
printf("Output array: "); /* not being displayed*/
}
}
And run it with ./a.out -n.
So, I have examined 0th and 1th character of the argv value on the position one ("./a.out" is located on position 0, and "-n" on position 1).
Is that what you wanted?
Also, you cannot ignore warnings:
1.c: In function ‘main’:
1.c:5:23: warning: passing argument 2 of ‘parse_cmdline’ from incompatible pointer type [-Wincompatible-pointer-types]
parse_cmdline(argc, argv);
^
1.c:3:6: note: expected ‘char *’ but argument is of type ‘char **’
void parse_cmdline(int argc, char *argv);
If you write
parse_cmdline(argc, argv);
then parse_cmdline should be
void parse_cmdline(int argc, char *argv[]);

Related

c- segmentation fault error due to calling a function that has text that user put in the terminal

Summary
I am trying to pass the text that user has put in the terminal and pass it to the function named printString(). I don't fully understand C but I think I has to do with the pointer not being in the heap. Any help would be appreacitaed!
#include <stdio.h>
void printString();
int main (int argc, char* argv[]) {
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, &argv);
}
return 0;
}
void printString(int commandAmount, char* argv[]) {
printf("the word is %s," , argv[commandAmount]);
}
./shortExample example
Segmentation fault (core dumped)
The prototype void printString(); does not match the actual implementation.
It should have been:
void printString(int commandAmount, char* argv[]);
You could also skip the prototype and just implement the function before main. Your loop while (commandAmount < argc) seems to not have any way to finish since you never increase commandAmount. This can cause undefined behavior and with such, your program may crash or do just about anything.
I suggest making a for-loop to fix that.
Example:
#include <stdio.h>
void printString(int commandAmount, char* argv[]) {
printf("the word is %s,", argv[commandAmount]);
}
int main(int argc, char* argv[]) {
for(int commandAmount = 1; commandAmount < argc; ++commandAmount) {
printString(commandAmount, argv);
}
}
or in the way you structured it:
#include <stdio.h>
void printString(int commandAmount, char* argv[]); // corrected
int main(int argc, char* argv[]) {
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, argv);
++commandAmount; // needed
}
}
void printString(int commandAmount, char* argv[]) {
printf("the word is %s,", argv[commandAmount]);
}
For starters this function declaration
void printString();
does not provide a function prototype. So the compiler determines the type of the parameters of the function from the function call
printString(commandAmount, &argv);
However the expression &argv used in this call
printString(commandAmount, &argv);
has the type char *** due to the declaration of the identifier argv
int main (int argc, char* argv[]) {
^^^^^^^^^^^^
But the corresponding parameter in the definition of the function printString has the type char ** due to adjusting by the compiler parameters having array types to pointers to array element type.
That is this function declaration
void printString(int commandAmount, char* argv[]) {
is adjusted by the compiler to
void printString(int commandAmount, char** argv) {
^^^^^^^^^^^
Thus there are incompatible types of the argument expression and of the parameter. As a result this call
printf("the word is %s," , argv[commandAmount]);
invokes undefined behavior.
Moreover this loop in main
int commandAmount = 1;
while (commandAmount < argc) {
printString(commandAmount, &argv);
}
in general is an infinite loop because the variable commandAmount is not changed within the loop.
Firstly you should provide the function prototype before main to make your program more safer
void printString(int commandAmount, char** argv);
and call the function like
printString(commandAmount, argv);
^^^^
Of course you need also to change the loop in main.
Pay attention to that as the value of the parameter commandAmount is not outputted within the function then in fact it is redundant. You could pass to the function the pointer to the string itself. For example
#include <stdio.h>
void printString( const char *s );
int main( int argc, char* argv[] )
{
for ( int commandAmount = 1; commandAmount < argc; commandAmount++ )
{
printString( argv[commandAmount] );
}
putchar( '\n' );
return 0;
}
void printString( const char *s )
{
printf( "the word is %s, " , s );
}

Programmatically calling main(int argc, char **argv) in C

Let's say I have a file test.c which accepts a text file and starts as follows:
int main(int argc, char **argv)
{
...
return 0;
}
I will typically compile the file and execute the binary as follows: ./test input.txt.
Now, I wish to call the main function programmatically in another function in the same file. How should I proceed?
You can do this as follows:
#include <stdio.h>
int main(int argc, char *argv[]);
void func()
{
char *argv[] = { "./test", "another.txt", NULL };
main(2, argv);
}
int main(int argc, char *argv[])
{
if (argc > 1) {
printf("Processing %s...\n", argv[1]);
}
/* ... */
func();
return 0;
}
This should output something like:
Processing input.txt...
Processing another.txt...
Beware of endless recursion!

C Warning passing argument 2 of ‘getopt’ from incompatible pointer type

I write a function with getopt() to get options from the command line. When I compile it, I get this Warning:
cc1: warnings being treated as errors
csim.c: In function ‘getArg’:
csim.c:157: error: passing argument 2 of ‘getopt’ from incompatible
pointer type /usr/include/getopt.h:152: note: expected ‘char * const*’
but argument is of type ‘const char **’
Here is the C code:
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
}
int getArg(int argc, char const *argv[], int *verbose, int *ps,
int *pE, int *pb, char *traceFileName){
int arg;
int argCount;
while ((arg = getopt(argc, argv, "vs:E:b:t:")) != -1){
switch (arg){
case 'v':
*verbose = 1;
break;
default:
printf("%s\n", "Illegal command arguments, please input again");
exit(-1);
break;
}
}
if(argCount < 4){
printf("%s\n", "Illegal command arguments, please input again");
exit(-1);
}
return 0;
}
The problem is, as the error says, you're passing a const char ** where a char * const* is expected. Specifically you're passing argv (which has the wrong type) to getopt. You could fix this by changing the type of argv.
int getArg(int argc, char * const argv[], int *verbose, int *ps, int *pE, int *pb, char *traceFileName)
It is the way your function has declared argv. You changed the constness. The error message is telling you what is wrong.

"Pointer from integer without cast" warning when opening file.

I have this homework to do in C. I'm beginner so it is probably very easy, but anyway I have a problem with it.
int main(int argc, char* argv){
int fd=open(argv[1], O_RDONLY);
int fileLength=(int)lseek(fd,0,SEEK_END);
lseek(fd,0,SEEK_SET);
char buf[fileLength];
read(fd,buf,fileLength);
int i=0;
for(i=0; i<fileLength; i++){
printf("%c",buf[i]);
}
printf("\n");
}
I get this error:
warning: passing argument 1 of ‘open’ makes pointer from integer without a cast
If I write "file" instead of argv[1], everything is ok.
int main(int argc, char* argv){
has to be:
int main(int argc, char *argv[])
See the error?
char* argv should be char* argv[]
What you did is declaring argv as char* and then argv[1] becomes a char (which is an integer) instead of char *
The correct signature is
int main(int argc, char **argv)
Your problem is in main() declaration, which should be:
int main(int argc, char *argv[])
You defined argv as a char *, which makes it a single pointer, whereas it's an array of char * pointer, with each char * element corresponding a command line argument to your program.
The error you're getting is caused by the fact that when you pass argv[1] to open(), argv[1] is a single char, while open() expects a char *.
Another improvement to your program would be checking that argc > 1 before attempting to use argv[1]. This would catch cases when you didn't pass any arguments to your program.
argv should be a char ** not a char * also you should run the program like
./program filename
Your main function's signature is wrong.
It should look like this:
int main(int argc, const char *argv[]) // notice how 'argv' is now a 'const char *[]',
Try this mate:
main () {
FILE *fin = fopen ("test.in", "r");
FILE *fout = fopen ("test.out", "w");
int a, b;
fscanf (fin, "%d %d", &a, &b); /* two input integers */
fprintf (fout, "%d\n", a+b);
exit (0);
}
instead of "test.in" put your argument, did you try to cast first before?

Passing command line arguments to app written in C

Here I wrote a little app which is able to read command line arguments
int main (int argc, const char * argv[])
{
int c;
while ((c = getopt (argc, argv, "Il:o:vh?")) != -1)
{
switch(c)
{
case 'I':
printf("I");
break;
}
}
return 0;
}
The problem is that when I try to compile it the compiler prints
warning: passing argument 2 of ‘getopt’ from incompatible pointer type
and program crash.
What I miss ?
The argv argument to main should have type char *[], not const char *[] so that it can be converted to the char *const [] that getopt expects. In fact, char *[] or equivalent is mandated by the C standard for hosted implementations.
int main (int argc, const char * argv[])
should be
//no const
int main (int argc, char * argv[])

Resources