1

I am supposed to create a program that takes a given file and creates a file with reversed txt. I wanted to know is there a way i can start the read() from the end of the file and copy it to the first byte in the created file if I dont know the exact size of the file? Also i have googled this and came across many examples with fread, fopen, etc. However i cant use those for this project i can only use read, open, lseek, write, and close. here is my code so far its not much but just for reference:

#include<stdio.h>
#include<unistd.h>

int main (int argc, char *argv[])
{
    if(argc != 2)/*argc should be 2 for correct execution*/
    {
        printf("usage: %s filename",argv[0[]);}
    }
    else
    {
    int file1 = open(argv[1], O_RDWR);
    if(file1 == -1){
    printf("\nfailed to open file.");
        return 1;
    } 
    int reversefile = open(argv[2], O_RDWR | O_CREAT);

    int size = lseek(argv[1],    0, SEEK_END);
    char *file2[size+1];
    int count=size;
    int i = 0

    while(read(file1, file2[count], 0) != 0)
    {
      file2[i]=*read(file1, file2[count], 0);
      write(reversefile, file2[i], size+1);
      count--;
      i++;
      lseek(argv[2], i, SEEK_SET);
   }
user2872131
  • 83
  • 2
  • 7
  • 3
    Suggestion: maybe it is easier to just read it in normally, but ouput in reversed order? – Pankrates Oct 11 '13 at 19:37
  • how would i do that without knowing the actual size of the file? – user2872131 Oct 11 '13 at 19:38
  • You *can* know the size of a file – Remo.D Oct 11 '13 at 19:38
  • Just read line by line and check for EOF, all the while keeping count of the number of lines read – Pankrates Oct 11 '13 at 19:38
  • @user2872131 1. You **do know** the file size (because you use `stat()`, `ftell()` and stuff). 2. Even if you don't: you read until end-of-file. –  Oct 11 '13 at 19:39
  • I don't think you get to know where the end of the file is until you get to it in C. In other words, until your `while (!feof(ifp)){}` stops whiling, you don't really know where you are with relation to the end of the file. Here is a link to some good C file I/O tips: http://www.cs.bu.edu/teaching/c/file-io/intro/ – zero298 Oct 11 '13 at 19:40
  • @SamIam I was more thinking along the line of ftell() as H2CO3 suggested. – Remo.D Oct 11 '13 at 19:40
  • `lseek` isn't necessary (but sure wouldn't hurt). There are a lot of ways to do this without it: **2 pass** - read it once to get the size, then allocate your memory. **dynamic buffer** - start with a fairly big buffer to read into, store the size read, and reallocate if necessary. For an example of reading to EOF using `open`, look at http://stackoverflow.com/questions/3180126/how-to-use-read-to-read-data-until-the-end-of-the-file (and apply the answer to the code sample) – Scott Mermelstein Oct 11 '13 at 20:34

3 Answers3

1

I doubt that most filesystems are designed to support this operation effectively. Chances are, you'd have to read the whole file to get to the end. For the same reasons, most languages probably don't include any special feature for reading a file backwards.

Just come up with something. Try to read the whole file in memory. If it is too big, dump the beginning, reversed, into a temporary file and keep reading... In the end combine all temporary files into one. Also, you could probably do something smart with manual low-level manipulation of disk sectors, or at least with low-level programming directly against the file system. Looks like this is not what you are after, though.

Sergey Orshanskiy
  • 6,794
  • 1
  • 46
  • 50
0

Why don't you try fseek to navigate inside the file? This function is contained in stdio.h, just like fopen and fclose.

Another idea would be to implement a simple stack...

someone
  • 361
  • 2
  • 3
  • 13
  • Most probably the simple stack is already implemented for him in the form of **recursion.** –  Oct 11 '13 at 19:40
  • for the project im doing im not supposed to used fopen, fread(), fwrite(), etc. – user2872131 Oct 11 '13 at 19:41
  • 1
    Then how are you reading the file? – someone Oct 11 '13 at 19:43
  • well from what ive learned i so far i need to use the system calls for this project. and the only way i know to read a file is to use the read() function but i wasnt sure how to do this if I didnt know the exact length of the file. – user2872131 Oct 11 '13 at 19:46
  • 1
    @user2872131 You check its return value, for starters... –  Oct 11 '13 at 19:47
  • 1
    `lseek` is part of unistd.h, and `lseek(file1, 0, SEEK_END)` will return the filesize. Not that I would recommend reading backwards, but it's still possible within these constraints. – Scott Mermelstein Oct 11 '13 at 20:03
  • Does lseek return an int value? – user2872131 Oct 11 '13 at 20:11
  • It seems to return the new offset within the file. When you start counting from the end (`SEEK_END`), and you move by zero positions, you get the index `i` of the last byte in the file. The size of the file must be `size = i + 1`. Have a look here: http://man7.org/linux/man-pages/man2/lseek.2.html for more information on lseek. – someone Oct 11 '13 at 20:21
  • ok so if i cast is as `int size = (int)lseek` this should give me the size of the file. Assuming off_t can be cast like that. – user2872131 Oct 11 '13 at 20:27
  • `int size = (int)lseek(file1, 0, SEEK_END) + 1;`, but I don't recommend it. You can use `stat` instead. – someone Oct 11 '13 at 20:37
  • @user2872131 Don't assume. Find the .h file that defines off_t, and **know**. – Scott Mermelstein Oct 11 '13 at 20:37
  • 1
    Casting off_t to int will likely work for your toy example, but will break if you need to handle large files so don't make a habit of it. On most 64-bit systems, and 32-bit systems if _FILE_OFFSET_BITS=64 is defined, off_t will be a 64-bit integer. – janneb Oct 11 '13 at 22:07
0

This has no error checking == really bad

  1. get file size using stat
  2. create a buffer with malloc
  3. fread the file into the buffer
  4. set a pointer to the end of the file
  5. print each character going backwards thru the buffer.

If you get creative with google you can get several examples just like this. IMO the assistance you are getting so far is not really even good hints. This appears to be schoolwork, so beware of copying. Do some reading about the calls used here. stat (fstat) fread (read)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

int main(int argc, char **argv)
{
   struct stat st;
   char *buf;
   char *p;
   FILE *in=fopen(argv[1],"r");   
   fstat(fileno(in), &st);         // get file size in bytes
   buf=malloc(st.st_size +2);      // buffer for file
   memset(buf, 0x0, st.st_size +2 );
   fread(buf, st.st_size, 1, in);  // fill the buffer
   p=buf;
   for(p+=st.st_size;p>=buf; p--)  // print traversing backwards
      printf("%c", *p);
   fclose(in);   
   return 0;
}
jim mcnamara
  • 16,005
  • 2
  • 34
  • 51
  • Thank you, however i have googled alot but most of the examples i came across used 'fread' 'fopen' etc. and yes this is schoolwork and I am not supposed to use them. I can only use 'read', 'open', 'lseek', and 'close'. and that is why I have been stuck and confused as to how I can read the file and copy its contents. – user2872131 Oct 11 '13 at 20:16
  • Most of what you need is there in the code. I assume you were given the syntax for those calls. I posted it this way because it is schoolwork. We are trying to help you learn, not do your homework. – jim mcnamara Oct 11 '13 at 20:30
  • i.e. lseek to the end of the file, read one character, print it, set the file pointer variable back one - (tell() gives you that), lseek there, read one print one -- until you are at the beginning of the file – jim mcnamara Oct 11 '13 at 20:33
  • ok i have edited my post and posted the while loop im using to read and create the file. The was one thing that i was confused with is the way im using the system calls, am i using them correctly? – user2872131 Oct 11 '13 at 21:32
  • @user2872131: Umm, well, at the time of writing this, no you aren't using them correctly. I recommend looking at the man page for read(), which describes which parameters it takes and in which order, what is the return value etc. – janneb Oct 11 '13 at 22:10
  • ok i have read the man page and i noticed that yes i have no clue how to use read. I fixed it so now is `read(file1, file2[size],0) however i am confused as to what goes in the last part. how big should an nbyte be? Also it says it returns the number of bytes read. so can i use that as a pointer to get the char? – user2872131 Oct 11 '13 at 23:00