0

Terrible coder here, this program I'm trying is to take user input and return it reversed in a new file. the kicker is using system calls (which I have just been exposed to). I am having trouble with my outputs. May someone please point out the error?

#include <fcntl.h>
#include <stdio.h>
#include "apue.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>


int main(){
    int fd1;
    int fd2;
    int offset;
    char readc;
    char filename[125];
    printf("Please enter the file you wish to reverse: ");
    scanf("%s", &filename);

    fd1 = open(filename, O_RDONLY);

    printf("open succesfully! File has been reversed and in a new file\n");

    if (fd1 < 0) { perror("Error! Can't open file\n"); exit(1); }


//create a new file
    fd2 = open("ReversedFile.txt", O_RDWR | O_CREAT, 0644);
    if(fd2 < 0){ perror("Error! Can't open file"); exit(1); }

    offset = lseek(fd1, 0, SEEK_END);
        while(offset > 0){
        read(fd1, &readc, 1);
        write(fd2, &readc, 1);
        lseek(fd1, -2, SEEK_CUR);
        offset--;
    }
close(fd1);
close(fd2);
return 0;
}

My first output where foo.txt contained exclamation points (which are invalid i discovered) is:

\00World Hello
!gnidoc ta kcus I
if this is readable i am correct

My second output however without exclamation point is:

 圀牯摬䠠汥潬朊楮潤⁣慴欠畣⁳੉晩琠楨⁳獩爠慥慤汢⁥⁩浡挠牯敲瑣

Why is this happening?

  • 1
    The reason is in UTF-8 codes. Open the file with hex editor and see. – i486 Feb 18 '21 at 07:25
  • 1
    Does this answer your question? [What is character encoding and why should I bother with it](https://stackoverflow.com/questions/10611455/what-is-character-encoding-and-why-should-i-bother-with-it) – tripleee Feb 18 '21 at 07:32
  • What was the input of 1st file? what is your required output? – Akash Dahane Feb 18 '21 at 14:08

1 Answers1

0

lseek(fd1, 0, SEEK_END) sets the file pointer at the end of the file. Then you try to read one byte which fails precisely because you are already at the end of the file and you don't check if read fails. If you had checked that, you would have found out that read returns 0 (meaning nothing has been read). Then you write the garbage value which is still in readc to the output file.

You want this:

  offset = lseek(fd1, -1, SEEK_END);      // seek to end of file -1 char
  while (offset >= 0) {
    int bytesread =read(fd1, &readc, 1);
    if (bytesread == 0)
    {
      perror("something went wrong with read\n");
      exit(1);
    }
    write(fd2, &readc, 1);
    lseek(fd1, -2, SEEK_CUR);
    offset--;
  }
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115