How to write int to file using write system call and read them exactly as written?

42,293

Solution 1

This is as simple as it can get (note that stdio.h is only included for printf; the read/write works without it):

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

int main()
{
    // Open file with write permission (create if doesn't exist).
    int fd = open("float.txt", O_CREAT | O_WRONLY);
    float val = 1.5f;
    if (fd != -1) {
        write(fd, &val, sizeof(val));
        close(fd);
    }

    // Test read.
    fd = open("float.txt", O_RDONLY);
    float new_val;
    if (fd != -1) {
        read(fd, &new_val, sizeof(new_val));
        printf("new_val = %f\n", new_val);
        close(fd);
    }
    return 0;
}

Solution 2

int foo;

write (fd, &foo, sizeof foo);

Solution 3

As ascertained in comments, the problem is more to convert a number to a decimal numeral than to use the write call.

To write an int or float that is readable by humans, you must convert it to a numeral, then write the characters of that numeral. For float, if the internal representation uses a different base (e.g., binary) than the numeral (e.g., decimal), then this requires a lot of work to do correctly. I would recommend either using existing open-source code or a scientific paper on the topic.

The code to convert an int to a decimal numeral is fairly straightforward:

#include <stdlib.h> //  For size_t.


/*  IntToString converts the int x to a decimal numeral, which is written to s.
    No terminal null character is written.  The number of characters written is
    returned.  s MUST point to space with enough room for the numeral,
    including a leading '-' if x is negative.
*/
size_t IntToString(char *s, int x)
{
    //  Set pointer to current position.
    char *p = s;

    //  Set t to absolute value of x.
    unsigned t = x;
    if (x < 0) t = -t;

    //  Write digits.
    do
    {
        *p++ = '0' + t % 10;
        t /= 10;
    } while (t);

    //  If x is negative, write sign.
    if (x < 0)
        *p++ = '-';

    //  Remember the return value, the number of characters written.
    size_t r = p-s;

    //  Since we wrote the characters in reverse order, reverse them.
    while (s < --p)
    {
        char t = *s;
        *s++ = *p;
        *p = t;
    }

    return r;
}


#include <stdio.h>  //  For printf.


//  Demonstrate IntToString.
static void Demonstrate(int x)
{
    char buf[100];
    size_t n = IntToString(buf, x);
    printf("IntToString(%d) = %.*s.\n", x, (int) n, buf);
}


#include <limits.h> //  For INT_MIN and INT_MAX.


int main(void)
{
    Demonstrate(0);
    Demonstrate(1);
    Demonstrate(9);
    Demonstrate(10);
    Demonstrate(INT_MAX-1);
    Demonstrate(INT_MAX);
    Demonstrate(-1);
    Demonstrate(-9);
    Demonstrate(-10);
    Demonstrate(INT_MIN+1);
    Demonstrate(INT_MIN);

    return 0;
}
Share:
42,293
Sam
Author by

Sam

A programmer programmed to program;

Updated on July 05, 2022

Comments

  • Sam
    Sam almost 2 years

    How can I write int, float or other types to a file using the write system call of UNIX? I want to do so without using any lib function like fprintf or fwrite.

    I want to use file descriptor and not the FILE*.

    After opening again, the file must be read exactly as written, without needing to know what size to read.