Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 499
Sam Avatar asked Apr 01 '13 16:04

Sam


People also ask

How do you write an integer using system call?

Code: int i=13; write(my_fd, &i, sizeof(i)); This stores the internal integer the way it is stored in memory inside the file.

What is write () system call?

The write is one of the most basic routines provided by a Unix-like operating system kernel. It writes data from a buffer declared by the user to a given device, such as a file. This is the primary way to output data from a program by directly using a system call. The destination is identified by a numeric code.

How do I print an int to write?

If you're trying to output an integer's value in human-readable form with write then you'll have to translate the value to chars yourself. To print a single digit, you add it to the char '0'. You should properly convert the int to string, then write the string.


3 Answers

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;
}
like image 154
Jengerer Avatar answered Sep 28 '22 07:09

Jengerer


int foo;

write (fd, &foo, sizeof foo);
like image 20
Barmar Avatar answered Sep 28 '22 05:09

Barmar


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;
}
like image 30
Eric Postpischil Avatar answered Sep 28 '22 05:09

Eric Postpischil