-1

I try to get strings which may be a filename from terminal argument. I wonder why it would come to segmentation fault.

#include <stdio.h>
#include <string.h>

int main(char *argv[]){

    char somefile[sizeof(argv)];
    strncpy(somefile,argv[0],sizeof(argv));

    printf("The file name is: %s", somefile);

    return 0;
}
Claudio Cortese
  • 1,372
  • 2
  • 10
  • 21
Kyrie Gu
  • 7
  • 2
  • 1) what do you expect `sizeof(argv);` to be ? 2) what does `strncpy()` do if `(strlen(2nd_argument) >= 3d_argument)` ? – wildplasser Feb 21 '18 at 20:04
  • 3
    `int main(char *argv[])` is not a valid prototype for `main` – Kevin Feb 21 '18 at 20:11
  • 3
    `int main(char *argv[])` is probably wrong, you should use `int main(int argc, char *argv[])` – M.M Feb 21 '18 at 20:13
  • See [What should `main()` return in C and C++](https://stackoverflow.com/questions/204476/) for a discussion of the correct signatures for `main()`. Hint: `int main(char *argv[])` is not a correct signature for `main()` on any normal platform — it should be `int main(int argv, char *argv[])` or equivalent (I use `int main(int argc, char **argv)` which is equivalent). – Jonathan Leffler Feb 21 '18 at 20:43
  • Great. I changed the arguments of main and it works. And also I found the comments about the length problem are also very helpful. Thx you guys! – Kyrie Gu Feb 22 '18 at 03:10

2 Answers2

2

Your statement:

strncpy(somefile,argv[0],sizeof(argv)); 

is handing the length of a pointer (i.e likely 4 or 8) to the 3rd argument instead of the actual size of the string. Change it to:

char somefile[strlen(argv[0])+1]; // note extra space for NULL terminator...
strncpy(somefile,argv[0],strlen(argv[0])+1); // ...here as well

Note, strncpy(dest, src, n) (for example) copies at most n characters of the character array pointed to by src. If n is reached before the entire array src was copied, the resulting character array, dest is not null-terminated. To mitigate this potential, you may consider doing the following:

char src[] = "this string is too long";
char dest[10];
int n = 10;
strncpy (dest, src, n);

results in dest containing:

|t|h|i|s| |s|t|r|i|n|?|?|?|...// may, or may not have a null terminator somewhere.  

dest[n-1] = 0;

results in dest containing:

|t|h|i|s| |s|t|r|i|\0|?|?|?|...// guaranteed NULL termination.

And since somefile was created so specifically based on argv[0]

strcpy(somefile,argv[0]);   

would do just as well in this situation.

ryyker
  • 22,849
  • 3
  • 43
  • 87
2

To get the length of argv you can just do strlen(argv[0]) instead.

Everything is kinda compounding off of that major issue. strncpy should be using the length of the string, other than that it seems like it should work.

Matthew Kerian
  • 812
  • 5
  • 18
  • "strncpy should be using the length of the string," --> I would not use the length of the string as that guarantees the target is not a string. Better to code base on the size of the target array. – chux - Reinstate Monica Feb 21 '18 at 20:55