Banka Don
Banka Don

Reputation: 43

write() and read() functions not working properly

I am trying to write a struct to a .dat file and when I open it it shows me this:

"1^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@041720881^@^@^@^@^@^@^@^@^@^@^@Denko^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@Brenko^@^@^@^@^@^@^@^@^@^@^@^@^@^@13.07.2000^@^@^@^@^@^@^@^@^@^@ "

It adds random symbols between the actual values. And now when I at least try to read and print some values, it just doesn't work. It's like the buffer is empty. But I followed the instructions and guides I read.

Using fwrite or similar is not an option since I have to work with these specific functions write() and read().

My code:

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

struct info{
    char id[20];
    char telefon[20];
    char ime[20];
    char priimek[20];
    char datum[20];
};
int main(int argc, char* argv[]) {
    struct info dude =
            {
                "01",
                "041720881",
                "Denko",
                "Brenko",
                "13.07.2000"
    };

    struct info dude2 =
            {
                "02",
                "041581734",
                "Denko",
                "Badenko",
                "13.07.1990"
            };

    if(strcmp(argv[1], "-c") == 0){

        int fd = open("xpo.dat", O_CREAT| O_APPEND | S_IRWXG, 0666);
        if(fd == -1){
            perror("Error while creating file");
            exit(EXIT_FAILURE);
        }
    }
    else if(strcmp(argv[1], "-o") == 0){
        struct stat sizefile;

        int fd = open("xpo.dat", O_RDWR);
        if(fd == -1){
            perror("Error while opening file");
            exit(EXIT_FAILURE);
        }       
        fstat(fd,&sizefile);
        int wr = write(fd, &dude,sizeof(struct info));

        char buf[101];
        int sz = read(fd, buf, 100);
        buf[sz] = '\0';
        if(sz == -1) {
            perror("Error while creating file");
            exit(EXIT_FAILURE);
        }
        printf("%s", buf);
        int cl = close(fd);
    }
    return 0;
}

Upvotes: 1

Views: 296

Answers (2)

anastaciu
anastaciu

Reputation: 23792

As stated in the comments and in the accepted answer, you have some issues, the why and the what is already talked about and explained.

I would like to add some more information:

And now when I at least try to read and print some values, it just doesn't work. It's like the buffer is empty.

What happens is that you are reading from the end of the file, if you want to read after you write without closing and reopening the file, you can, but you'll need to reposition the offset of the opened file to the beginning using lseek.

Another thing to note is that if you want to write the data as a structure you then need to read it as a structure as well, not as a string.

Taking that in consideration your code could look more or less like this (skipping return value validations, but you should do it, as you know):

//...
else if(strcmp(argv[1], "-o") == 0){

    int fd = open("xpo.dat", O_RDWR);  
    int wr = write(fd, &dude, sizeof dude);
    lseek(fd, 0, SEEK_SET); // set the reading position to the beginning of the file
    struct info buf;
    wr = read(fd, &buf, sizeof buf);
    int cl = close(fd);
    printf("%s %s %s %s %s", buf.id, buf.telefon, buf.ime, buf.priimek, buf.datum);
}
//...

If you prefer it as a string you can easily concatenate it using something like snprintf or similar.

Upvotes: 3

mkayaalp
mkayaalp

Reputation: 2716

The struct contains 100 chars of data. But you are setting only some of them. When you set ime as Denko, the first six chars are set as 'D', 'e', 'n', 'k', 'o','\0'. The remaining 14 are not initialized (or rather initialized implicitly, see @dave_thompson_085's comment below).

If you want to omit those chars, you cannot write the struct as one block. Either write each field separately, or concatenate the fields into a string and write it instead.

Upvotes: 5

Related Questions