0

I have to make a function in C that can swap a file extension into another. For instance:

swapExtension("myFile.c", "o");

and the prototype is:

char * swapExtension(char * fileName, char * fileExtension).

I am not getting anything but a segfault. My code is:

{
    char * temp = strchr(fileName, '.');
    printf("%s",temp);
    strncpy(temp, nouvelleExtension, 2);
}
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
user2417992
  • 204
  • 1
  • 6
  • 16
  • 1
    You are probably passing in a pointer to a literal string "myFile.c", then writing to it in your function. Depending on the platform, this can easily segfault. You have to create a buffer to work on, and manipulate the string there. – Baldrick Oct 22 '13 at 12:33
  • Please don't use profanities on SO; thanks @hopper – Bathsheba Oct 22 '13 at 12:34
  • nomFic is fileName, I just fixed it. – user2417992 Oct 22 '13 at 12:42
  • Try using: char filename[] = "myFile.c"; and calling swapExtension(filename, "o"); This way you are declaring a char array initialized with the string characters and sized to the literal string size. Warning: This will get you an error if you try to write longer extensions (e.g. ".obj" on a ".c" filename). More info here: http://stackoverflow.com/a/164229/253111 – Guarita Oct 22 '13 at 12:49
  • Check for NULL pointer `if(temp == NULL) { printf("Null string");}`. This will give your clue on what is going on in your code. – Anand Oct 22 '13 at 12:54

2 Answers2

1

There are two problems in your code 1) You are using the char * are are trying to modify that protected memory inside your code

2) You are trying to return a local address from your function which is also not good.

3) What if the filename contains a DOT '.' in its filename.

You can use char array as a solution but still the second problem remains, for that you should allocate some memory and then copy the returning string into that memory

char* swapExtension(char * fileName, char * fileExtension)
{
int newext = strlen(fileExtension);
bool flag =false;
int size = strlen(fileName);
int ext = 0;
for(int i=size-1;i>=0;i--)
{
    if(fileName[i] == '.')
    {
        flag = true;
        ext = (size -1) - i;
        break;
    }
}
if(!flag){
    printf("no extension found");
    return NULL;
}
int retsize = size - ext + newext + 1;
char * retBuff = new char[retsize];
retBuff[0]='\0';
memcpy(retBuff,fileName,retsize);
strncpy(&retBuff[size-ext], fileExtension, newext);
return retBuff;

}

kunal
  • 956
  • 9
  • 16
  • Or use [`strrchr`](http://en.cppreference.com/w/c/string/byte/strrchr) instead. Also your code contains a syntax error on the line `char * retBuff = new char[retsize];` (OP is using C, not C++). – Kninnug Oct 22 '13 at 13:04
  • ok...that can be changed to malloc. – kunal Oct 22 '13 at 13:22
0

As Baldrick mentioned, you're passing a (pointer to) string constant to swapExtension, you then pass that string constant to strchr which in turn returns a part of that same string constant. Then with strncpy you write to the string constant which is undefined behaviour and in your case segfaults.

Use a string (character) array instead:

char myFile[] = "myFile.c";
swapExtension(myFile, "o");

Now temp in swapExtension will write to the myFile array which is valid. Though, be aware that this will only work when the length of the extensions is the same, otherwise there won't be enough space in the array. To prevent this, use:

char myFile[50] = "myFile.c";

The array will initially contain the same string but will also have space for a longer one.

See also: What is the difference between char s[] and char * s in C

Community
  • 1
  • 1
Kninnug
  • 7,992
  • 1
  • 30
  • 42