4

I want to delete the last char of a text file. I have a code that saves strings and I need to delete only the last '\n'.

I already tried to do:

fseek(fp, -1, SEEK_END);
fputs("", fp);

Here's the full code:

void saveGIF(FrameNode** head)
{
    FILE* fp = 0;
    FrameNode* curr = *head;
    int i = 1;
    int howManyFrames = framesInList(head);
    char c = 0;
    char filePath[SIZE] = { 0 };

    if (curr == NULL)
    {
        printf("Nothing to save, add more frames and than save\n");
    }
    else
    {
        printf("Where to save the project? enter a full path and file name\n");
        getchar();
        myFgets(filePath, SIZE);
        fp = fopen(filePath, "w+");
        if (fp != NULL)
        {
            while (curr)
            {
                fprintf(fp, "%s %d %s\n", curr->frame->name, curr->frame->duration, curr->frame->path);
                curr = curr->next;
                i++;
            }
            fseek(fp, -1, SEEK_END);
            fputs("", fp);
            fclose(fp);
        }
        else
        {
            printf("Error! canot create file\n");
        }
    }
}
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • You might have to write a whole new file, although it would seem like there should be a reasonable solution to this. I doubt it will involve `fputs` if it does exist though. – Mad Physicist Jun 21 '18 at 19:20
  • 1
    Platform? On POSIX, the answer is [`ftruncate()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html) or [`truncate()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html). On Windows, the answer will probably be different. – Jonathan Leffler Jun 21 '18 at 19:22
  • The second top scoring answer in the duplicate covers Windows and has some comments related to Win64 etc. My answer there also has links — to MSDN and to the other answer. – Jonathan Leffler Jun 21 '18 at 19:31
  • You could overwrite the final newline with a blank using `fputs(" ", fp)`, but writing an empty string doesn't change the file content. You could also use `fwrite()` to write a null byte over the newline. However, neither of those shortens the file, unlike `truncate()` and its related functions. – Jonathan Leffler Jun 21 '18 at 19:33
  • Why do you want to do that? Text files should always end with a newline character. – rici Jun 21 '18 at 22:01
  • 1
    @user3121023 thank you so mach your answer is perfact – Daniel Shinar Jun 21 '18 at 23:16

1 Answers1

2

In ISO C, the only way to do this is to write out a new copy of the entire file under a temporary name, and then use rename to change its name to the old name. There is no way to shorten a file in place. (If you are on Windows you may have to remove the old name before rename will work.)

POSIX adds the ftruncate operation which can be used to make a file shorter (or longer) in place. Most common operating systems support POSIX features, but Windows doesn't. Depending on which compiler you have on Windows, you might still have a function named ftruncate, though, because the C runtime on Windows often tries to fake a subset of POSIX functionality -- many of those fakes are unreliable, but I confess I don't see how one could screw up ftruncate given that Windows proper does have an equivalent primitive operation, it just has a different name (SetEndOfFile).

zwol
  • 135,547
  • 38
  • 252
  • 361