tags:

views:

134

answers:

3

I want to write some bogus text in a file ("helloworld" text in a file called helloworld), but not starting from the beginning. I was thinking to lseek() function.

If I use the following code (edited):

#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>

#define fname "helloworld"
#define buf_size 16

int main(){

    char buffer[buf_size];
    int fildes,
        nbytes;
    off_t ret;

    fildes = open(fname, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR);
    if(fildes < 0){
        printf("\nCannot create file + trunc file.\n");
    }
//modify offset
    if((ret = lseek(fildes, (off_t) 10, SEEK_END)) < (off_t) 0){
        fprintf(stdout, "\nCannot modify offset.\n");
    }
    printf("ret = %d\n", (int)ret);

    if(write(fildes, fname, 10) < 0){
        fprintf(stdout, "\nWrite failed.\n");
    }

    close(fildes);

    return (0);
}

, it compiles well and it runs without any apparent errors. Still if i :

cat helloworld

The output is not what I expected, but:

helloworld
Can

Where is "Can" comming from, and where are my empty spaces ?

Should i expect for "zeros" instead of spaces ? If i try to open helloworld with gedit, an error occurs, complaining that the file character encoding is unknown.

LATER EDIT: After I edited my program with the right buffer for writing, and then compile / run again, the "helloworld" file still cannot be opened with gedit.strong text

LATER EDIT I understand the issue now. I've added to the code the following:

fildes = open(fname, O_RDONLY);
if(fildes < 0){
    printf("\nCannot open file.\n");
}

while((nbytes = read(fildes, c, 1)) == 1){
    printf("%d ", (int)*c);     
}

And now the output is:

0 0 0 0 0 0 0 0 0 0 104 101 108 108 111 119 111 114 108 100

My problem was that i was expecting spaces (32) instead of zeros (0).

+1  A: 

Your buf_size doesn't match the length of fname. It's reading past the buffer, and therefore getting more or less random bytes that just happened to sit after the string in memory.

Matti Virkkunen
+2  A: 

In this function call, write(fildes, fname, buf_size), fname has 10 characters (plus a trailing '\0' character, but you're telling the function to write out 16 bytes. Who knows what in the memory locations after the fname string.

Also, I'm not sure what you mean by "where are my empty spaces?".

Michael Burr
From my book: "On its own, seeking past the end of a file does nothing—a read request to the newlycreated file position will return EOF. If a write request is subsequently made to thisposition, however, new space will be created between the old length of the file andthe new length, and it will be padded with zeros." I realize now that zeros aren't spaces. Is it because of those zeros I cannot open the file with a regular text editor ?
Andrei Ciobanu
What do you mean by "cannot open"? What happens when you try to? If you want to know what's really going on, view a hex dump of the file (for instance, by opening your shell and doing cat helloworld|xxd)
Matti Virkkunen
+1  A: 

Apart from expecting zeros to equal spaces, the original problem was indeed writing more than the length of the "helloworld" string. To avoid such a problem, I suggest letting the compiler calculate the length of your constant strings for you:

    write(fildes, fname, sizeof(fname) - 1)

The - 1 is due to the NUL character (zero, \0) that is used to terminate C-style strings, and sizeof simply returning the size of the array that holds the string. Due to this you cannot use sizeof to calculate the actual length of a string at runtime, but it works fine for compile-time constants.

The "Can" you saw in your original test was almost certainly the beginning of one of the "\nCannot" strings in your code; after writing the 11 bytes in "helloworld\0" you continued to write the remaining bytes from whatever was following it in memory, which turned out to be the next string constant. (The question has now been amended to write 10 bytes, but the originally posted version wrote 16.)

The presence of NUL characters (= zero, '\0') in a text file may indeed cause certain (but not all) text editors to consider the file binary data instead of text, and possibly refuse to open it. A text file should contain just text, not control characters.

Arkku