开发者

C: lseek() related question

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 "he开发者_运维问答lloworld"
#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).


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?".


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜