Search code examples
cgetlineatoi

Write int to binary file in C


I have to open a file, which contains every number in new line. ( represented as string )
To read data I need to use getline().
To change data from string to int, I need to use atoi().
To write changed data to file, I need to use write().

What I managed to do is this:

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

int main()
{
    FILE *stream;
    stream = fopen("stevila.txt", "r");

    FILE *fd = fopen("test.bin", "w+");

    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    int a=10;
    char str[8192];


    while ((read = getline(&line, &len, stream)) != -1) {
        strcpy(str, line);
        int val = atoi(str);
        write(fd, val, a);
    }

    free(line);
    fclose(stream);
}

EDIT :
Thanks to the answers, I managed to create a program that works :

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int main()
{
    FILE *f = fopen("text.txt","r");

    mode_t mode = S_IRUSR | S_IWUSR; /* Allow user to Read/Write file */
    int fd = open("out.bin",O_WRONLY|O_CREAT|O_TRUNC,mode);

    if (f==NULL) {
        perror("Error while opening 'text.txt' ");
        return -1;
    }
    if(fd < 0){
        perror("Error while opening 'out.bin' ");
        return -1;
    }

    size_t max_size=64;
    char* line;
    line=malloc(max_size);

    int d;
    while ((d=getline(&line, &max_size, f))!=-1)
    {
        int tmp=atoi(line); /* Change string to int and save it to tmp */
        if(write(fd,&tmp,sizeof(tmp)) == -1)
        {
            perror("Error while writing data ");
            break;
        }
    }

    fclose(f);
    close(fd);
    free(line);

    return 0;
}

Now we can run this command in terminal, to see if the output file is as expected:

od -i out.bin

Solution

  • You cannot use a FILE* as an argument to write. You have the following options:

    1. Use fwrite. The signature of fwrite is:

      size_t fwrite( const void *buffer, size_t size, size_t count,
                     FILE *stream );
      
    2. Get the file descriptor from a FILE* using the function fileno and use write. The signature of fileno is:

      int fileno(const FILE *stream);
      

      The signature of write is

      ssize_t write(int fildes, const void *buf, size_t nbyte);
      

      Your use of write is not correct. You are passing a val, which is not the address of a variable. You are using a as the third argument. That needs to be changed to:

      write(fd, &val, sizeof(val));
      
    3. Use open instead of fopen.

    My recommendation will be to use fwrite. It is a standard C library function whereas write is not.

    Also, make sure to open the file in binary mode. Instead of using "w+", use "wb".

    FILE *fd = fopen("test.bin", "wb");
    

    Add a line to close the file before exiting. If you use fopen to open the file, use fclose to close it. If you use open to open the file, use close to close it.