user21290559
user21290559

Reputation: 47

Why does printf not print anything?

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

Answers (3)

SztupY
SztupY

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

Lundin
Lundin

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

MikeCAT
MikeCAT

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

Related Questions