Reputation: 47
I have this code where I take a file name and generate a new file with the same file name but ending in .c
However, when I attempt to transform the file name to end in a .c, I try to print the result to check if it's working. And printf just prints nothing. If it makes a difference, the file name is a pointer that points to argv[1] from int main(int argc, char *argv[]).
Here is the code:
bool file_genEquiCFile(char *file_name)
{
// Maybe add a memmove to preserve the original buffer
printf("file_name before change: %s\n", file_name);
while (file_name && *file_name != '.')
file_name++;
if (file_name)
{
if (*file_name++ == '.')
{
*file_name++ = 'c';
*file_name = '\0';
// For now use "w" mode which makes an empty file for writing.
FILE *c_file = fopen(file_name, "w");
fclose(c_file);
printf("file_name after change: %s\n", file_name);
return true;
}
else
return false;
}
return false;
}
By the way, file_name points to a file called hey.txt Here is what printf printed:
file_name before change: hey.txt
file_name after change:
Upvotes: 0
Views: 661
Reputation: 10546
The problem is that you are not only changing the contents of the string file_name
, you are also changing the pointer on where the file_name
string starts. By the time you're getting to the printf
your pointer points to only the \0
part, and that's what printf
will print out for you: an empty string.
There are various ways to solve this, likely the easiest is to save your pointer at the start which still points to the start of the string and make sure you use that whenever you need to refer to the new filename:
char* file_name_save = file_name;
(...)
FILE *c_file = fopen(file_name_save, "w");
fclose(c_file);
printf("file_name after change: %s\n", file_name_save);
Do note that you are still modifying the underlying string in the memory, so if this would be a function, the contents of the file_name
(the string) for the caller would change as well. If this is not what you want you'll have to copy the string first before doing any updates on it.
Upvotes: 2
Reputation: 214860
while (file_name && *file_name != '.')
doesn't make any sense. The left operand checks if file_name
is a null pointer. That's wrong, you should check if the contents pointed at is the null terminator:
while (*file_name != '\0' && *file_name != '.')
Similarly if (file_name)
doesn't make any sense, should have been if (*file_name)
or if (*file_name != '\0')
.
As for if what the code is supposed to do even make sense in the first place, I cannot tell.
Upvotes: 1
Reputation: 75062
After *file_name = '\0';
, file_name
points at a 0-character string because what file_name
points at is the terminating NUL character.
You should store the original file_name
at the beginning of the function and use it later instead of the modified file_name
later.
bool file_genEquiCFile(char *file_name)
{
char *file_name_orig = file_name;
// Maybe add a memmove to preserve the original buffer
printf("file_name before change: %s\n", file_name);
while (file_name && *file_name != '.')
file_name++;
if (file_name)
{
if (*file_name++ == '.')
{
*file_name++ = 'c';
*file_name = '\0';
// For now use "w" mode which makes an empty file for writing.
FILE *c_file = fopen(file_name_orig, "w");
fclose(c_file);
printf("file_name after change: %s\n", file_name_orig);
return true;
}
else
return false;
}
return false;
}
Also you may want to use *file_name
instead of file_name
in the first while
and if
to check not if the pointer is not NULL
but if what the pointer points at is a NUL character.
Upvotes: 1