2

I need to write out .txt file backwards in terminal using recursion, but it seems I'm stuck. This is my code so far, but it creates an infinite loop. Also, the procedure write() should have only 1 parameter - pointer to file.

#include <stdio.h>

void write(FILE **f)
{
    char cur;

    fseek(*f,-1,SEEK_CUR);
    cur = fgetc(*f);

    printf("%c",cur);
    write(f);
}

int main(void)
{
    FILE *f;
    f = fopen("text.txt","r");
    fseek(f, 0, SEEK_END);
    write(&f);
    
    fclose(f);
    return 0;
}

I wanted to use fseek and ftell functions, they seem to be best way to do this. My expected output would be: FILE Hello world OUTPUT dlrow olleH

Cassie
  • 43
  • 4
  • Considering they have a infinite call stack, they won't even be able to see the print outputs. – Rohan Asokan Jan 02 '21 at 13:50
  • @Cassie can you please provide the outputs in the file, if any? – Rohan Asokan Jan 02 '21 at 13:51
  • Your recursive function has no termination criteria. It always makes the recursive call, so it goes on forever until stack overflow. You need logic in a recursive function that decides whether to make the recursive call or not. – lurker Jan 02 '21 at 13:56
  • @RohanAsokan Right now my output is *dddddddddddddd* until I stop the program. – Cassie Jan 02 '21 at 13:57

2 Answers2

0

This task is actually not very suitable for the recursion but ..

EDIT I actually misunderstood your question but it is same trivial.

#include <stdio.h>
#include <string.h>

void writeRecursive(FILE *file)
{
    int ch;
    if(fread(&ch, 1, 1, file) == 1) 
    { 
        writeRecursive(file);
        fwrite(&ch, 1, 1, file);
    }
    else
    {
        rewind(file);
    }

}

int main(void)
{
    FILE *fi = fopen("a.txt", "w+");
    char c;

    fprintf(fi, "123456789");
    rewind(fi);

    writeRecursive(fi);
    rewind(fi);
    while(fread(&c, 1, 1, fi) == 1)
    {
        printf("%c", c);
    }
    printf("\n");
}

https://godbolt.org/z/edGfKa

or

void writeRecursive(FILE *file)
{
    int ch;
    if((ch = fgetc(file)) != EOF) 
    { 
        writeRecursive(file);
        fputc(ch, file);
    }
    else
    {
        rewind(file);
    }

}

Old answer

void printRecursive(FILE *fi, FILE *fo)
{
    char ch;
    if(fread(&ch, 1, 1, fi) == 1) 
    { 
        printRecursive(fi,fo);
        fwrite(&ch, 1, 1, fo);
    }

}

int main(void)
{
    FILE *fi = stdin, *fo = stdout;

    printRecursive(fi, fo);
}

https://godbolt.org/z/YjfvcP

0___________
  • 60,014
  • 4
  • 34
  • 74
0

From what you have given, the way to do the problem recursively using fseek and ftell can be written as follows,

#include <stdio.h>

void write(FILE **f)
{
    char cur;
    cur = fgetc(*f);
    printf("%c", cur);
    if (ftell(*f) == 1) return;
    fseek(*f,-2,SEEK_CUR);
    write(f);
}

int main(void)
{
    FILE *f;
    f = fopen("text.txt","r");
    fseek(f, -1, SEEK_END);
    write(&f);
    
    fclose(f);
    return 0;
}

Considering the file is read in reverse, the stop condition requires a bit of thinking. The position of a pointer is returned by ftell and using this we can detect if the current position of the pointer is at the start of the file or not (as in if it is equal to 1).

There were tiny mistakes in your code - the recursion never stopped (as pointed out in the comments), make sure you always have a stop inside your recursive functions.

The order of your fseek needs changing so that you read the first character in properly.

And you need to use a -2 inside your fseek to move to the previous character. This is because of the fact that fgetc will advance the pointer by 1 and you will have to go back by 1 character to reach the character that was read just now and you then you want to move it backwards by one more, so that you get to the character before the one that was just read. Thanks to p-j-supports-women-in-poland for pointing this out.

Otherwise the above code will make it clear for you, I hope. if you still got doubts ping me in the comments. Happy to help :)

Rohan Asokan
  • 634
  • 4
  • 22