-1

I wanted to read the file that is given in command line arguments and delete it after reading . This is what I'm doing.

char *filename = argv[1];
char *outputfile = strcat(argv[1], ".cmp");

fd = open(argv[1], O_RDONLY);
chars = read(fd, buf, BUFFERSIZE);
fd1 = creat(outputfile, 0644);
write(fd1, buf, BUFFERSIZE);
close(fd1);
close(fd);
unlink(argv[1]);

If I give "mytxt" in the command line, the code is supposed to create "mytxt.cmp" file and delete "mytxt", instead it is deleting "mytxt.cmp" keeping "mytxt" as it is. Why is it so? How can I delete a file given in command line arguments.

19285496
  • 71
  • 1
  • 3
  • 7
  • 2
    I'm wondering how much it would have hurt to read the documentation of `strcat()`. –  Feb 28 '13 at 21:55
  • 2
    To be fair, no one reads the documentation for things they think they understand, but are in fact wrong about. –  Feb 28 '13 at 21:59
  • 1
    @wilsonmichaelpatrick: I'd say in way too many cases it's worse than that: people don't read the documentation regardless of whether they think they understand it or not and simply ask here... – NotMe Mar 01 '13 at 03:06
  • @wilsonmichaelpatrick Maybe you do that, but don't accuse others of doing so. I tend to read the docs when I am about to use a new function/class/API even if I've seen code using it before and I think I understand it. –  Mar 01 '13 at 05:43

2 Answers2

5
char *outputfile = strcat(argv[1], ".cmp");

You are modifying argv[1], and filename points to it. You could try making a new string with malloc and sprintf-ing the required value into it.

char *newstr = malloc(strlen(argv[1]) + strlen(".cmp") + 1);
sprintf(newstr, "%s.cmp", argv[1]);
cnicutar
  • 178,505
  • 25
  • 365
  • 392
  • 3
    And not only modifying, but also writing past its end -> **UB!**. –  Feb 28 '13 at 21:53
  • Well, writing past the end of a string doesn't *necessarily* cause a problem. The size of `argv[1]` might be longer than the string it contains, for example. That said, it's probably not a smart move, since you don't really have any way to find out if it's safe or not. – Carl Norum Feb 28 '13 at 21:54
4

This is not good, and is the cause of your problem:

char *outputfile = strcat(argv[1], ".cmp");

What this does is:

1) Appends ".cmp" to argv[1]. Don't do this! You don't know how much space is in the buffer that argv[1] points to, so this is likely to overwrite/corrupt some other data. 2) strcat returns a pointer to the concatenated string, which is just argv[1] with ".cmp" dangerously added at the end. strcat does not allocate space for a new string. 3) So what you've really done is appended ".cmp" to the original, so both argv[1] and outputfile point to the same string, and possibly corrupted some memory.

What you should do is allocate space for a string:

char* outputfile = (char*)(malloc(strlen(argv[1]) + strlen(".cmp") + 1));
sprintf(outputfile, "%s.cmp", argv[1]);

and then at the end give back the memory.

free(outputfile);