0

I want to open a new file and write a char array to it, but when I read back the contents of the file it has what I wrote to it followed by a bunch of garbage characters.

I want to map the file to memory, but when I read the file back from that map, I am getting those random characters following it.

...
char *towrite = "12345"

int fd = open("file.txt",  O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

struct stat sb;

write(fd, &towrite, sizeof(towrite));

if(fstat(fd, &sb) != -1){
     printf("file is %ld bytes long.\n", sb.st_size);
}

char *mappedfile = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

for(int z=0; z < sb.st_size; z++){
     printf("%c", mappedfile[z]);
}
printf("\n");
close(fd);
...

I've also noticed that the file size comes back as 1790 bytes which really doesn't seem right when I'm only writing a char array that is so small.

Forgive me for my insolence, I'm totally new to file reading and writing, as well as file mapping. I just can't seem to find what I am doing wrong with the documentation I've found online.

Thanks!

M.M
  • 138,810
  • 21
  • 208
  • 365
thebaconator
  • 223
  • 6
  • 10
  • You are 1. trying to get the size of a string with `sizeof` (use strlen) 2. trying to get the address of the character data with `&` (`char*` is already a pointer, just use it). I don't know how it got to 1790 bytes though, it should only be ~8. – that other guy Mar 31 '20 at 22:21
  • `sizeof(towrite)` is unrelated to the amount of data stored at `towrite` – William Pursell Mar 31 '20 at 22:26

1 Answers1

2

This line is not what you want:

write(fd, &towrite, sizeof(towrite));

This writes the value of the pointer towrite to the file, rather than the string to which it points. Moreover, for a pointer, sizeof is the size of the pointer, not the size of what it points to.

You probably want

write(fd, towrite, strlen(towrite));

You could also change towrite to an array and do

char towrite[] = "12345";
write(fd, towrite, sizeof(towrite));

but then the terminating null byte will also be written, unless you use sizeof(towrite)-1 instead.

Also, you are not using the flag O_TRUNC when opening, so the file will not be truncated: if the file already exists, any data already in the file beyond the 5 bytes you are writing will stay there. Your 1790 bytes may be left over from previous testing. If you want to erase the previous contents and start over with an empty file, open with flags O_RDWR | O_CREAT | O_TRUNC.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82