C программирование: запись () целых чисел в текстовый файл - PullRequest
0 голосов
/ 03 июня 2019

Я пытаюсь записать пару целых чисел в текстовый файл, используя sys-вызов write (), но вместо цифр я получил странные символы ( 00 \ 00 \ 00 \ 00 \ 00 \ 00 ).

Gedit сообщает мне, что существует проблема с кодировкой, и что файл отсутствует в UTF-8.Я компилирую с gcc, который должен иметь кодек UTF-8, установленный по умолчанию.Я решил '\ 00', изменив sizeof (i) на 1, но не могу разрешить числа.

int main(int argc, char const *argv[]) {
   int fd=open("test.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
   int i = 2;
   write(fd, &i, sizeof(i)); }

Ответы [ 3 ]

3 голосов
/ 03 июня 2019

Вы должны понимать, как числа представлены в компьютере: когда вы читаете 2 на экране, то, что на самом деле хранится в памяти, это число 50.

Это код для символа 2 в таблице ASCII .

Фактическое число 2 не соответствует печатному символу, то есть символу, который вы можете прочитать на экране, поэтому различные текстовые редакторы, такие как Gedit, будутведут себя по-разному: некоторые будут отображать квадраты или точки, другие будут показывать число с некоторыми экранирующими символами '\'.

UTF-8 на самом деле обратно совместим с ASCII, так как он дает английский алфавит, цифры инекоторые другие символы имеют те же коды, что и ASCII.

Целочисленная переменная содержит фактическое число, с которым компьютер может выполнять вычисления, а не символы, которые вы, как человек, можете прочитать.

Если вы используете32-битная ОС, int в C будет 32 бит или 4 байта.Поскольку вы, скорее всего, используете процессор x86, число будет повторно представлено в порядке little-endian .

Итак, когда вы записываете эти байты в файл с вашим кодом, файл будет выглядеть следующим образомна диске:

+---+---+---+---+
| 2 | 0 | 0 | 0 |
+---+---+---+---+

Gedit попытается прочитать его как 4 символа, но не сможет распечатать их, поэтому он покажет вам их значение, которому предшествует хартия '\', так что вы будете знать, что это специальныенепечатаемые символы.

Существует два способа использования write() и получение нужного текстового представления.
Во-первых, вам необходим массив char для создания строкового представления числа.

Затем вы можете сделать одну из двух вещей:

  1. Обман и использовать sprintf, чтобы легко отформатировать число в строку.
  2. Выполните работусамостоятельно с циклом и некоторой простой математикой, и конвертируйте каждую десятичную цифру в номере в ее символ ASCII.
    Вот подсказка: просто добавьте 0x30 (шестнадцатеричное 30)
1 голос
/ 03 июня 2019

Для записи в текстовый файл гораздо проще использовать fopen:

#include <stdio.h>
int main(int argc, char const *argv[]) {
    FILE *int fp = fopen("test.txt", "w");
    if (fp) {
        int i = 2;
        fprintf(fp, "%d\n", i);
        fclose(fp);
    }
}

, если вам нужно использовать open (2), вы можете сделать это следующим образом:

int main(int argc, char const *argv[]) {
    int fd = open("test.txt", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
    if (fd != -1) {
        int i = 2;
        char tempbuf[13];
        int bytes = sprintf(tempbuf, "%d\n", i);
        if (bytes > 0)
            write(fd, tempbuf, bytes);
        close(fd);
    }
}

Вам нужно будет определить правильный размер буфера для целых чисел, которые вы пишете, и кодировку.

1 голос
/ 03 июня 2019

write запишет двоичное представление int, например 8 байтов, образующих 64 бита целочисленного значения, непосредственно в файл. Там нет преобразования в ASCII или UTF8 «символы», как вы ожидаете при открытии файла в текстовом редакторе. Интегральное значение 2 в двоичном виде - 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x02, и это то, что вы «видите» в своем файле. Текстовое представление будет 0x32, то есть значение ASCII цифры 2.

Используйте snprintf для преобразования целочисленного значения в текстовое представление и затем запишите его в файл:

int i = 2;
char str[50];
snprintf(str, 50, "%d\n", i);
write(fd, str, strlen(str));
...