#c #io
#c #io
Вопрос:
Я пытаюсь получить значение первого символа в файле с помощью функции чтения из unistd, и у меня возникают проблемы со странным поведением :
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main() {
char uselessTable[600];
int fdInput;
int firstChar;
if ((fdInput = open("file.txt", O_RDONLY)) == -1) {
perror("file");
_exit(1);
}
read(fdInput, amp;firstChar, 1);
printf("Taille du nom de fichier : %dn", firstChar); // prints 32609
if (close(fdInput) == -1) {
perror("close");
_exit(2);
}
}
Файл содержит строку abc, поэтому он должен печатать число 97, но это не так, если я не удалю таблицу uselessTable, даже если она не используется в этой программе.
Изменение размера таблицы на 500, ее удаление, создание после firstChar или изменение int firstChar на char firstChar, похоже, решает проблему, но я не понимаю почему.
Комментарии:
1. Это потому, что read() перезаписывает только первый байт firstChar int, что приводит к неопределенному поведению. Сделайте firstChar символом char и преобразуйте его в int при использовании printf() для него.
2. Вы считываете один байт в an
int
(который занимает более одного байта), оставляя другие байты неинициализированными.
Ответ №1:
Давайте пройдемся по этому шаг за шагом. Сначала вы создаете локальную переменную firstChar
, которая является an int
, а не a char
. Локальные переменные, которые не инициализированы (и которые не static
инициализированы), могут быть установлены в любое произвольное значение.
Для простоты скажем, что int
тип данных на самом деле имеет длину четыре байта.
Следующий шаг заключается в том, что вы считываете одну char
переменную в адрес этого четырехбайта int
. Итак, в итоге вы получаете память:
----- ----- ----- -----
firstChar: | 'a' | ? | ? | ? |
----- ----- ----- -----
для первого байта этого int
значения установлено значение 97 (при условии ASCII), а для других байтов все еще установлено некоторое произвольное значение.
Поскольку целое число состоит из всех четырех байтов, вот почему вы получаете что-то вроде 32609
.
Очевидным решением является использование char
переменной, которая будет использовать только один байт. Таким образом, когда вы перезаписываете этот байт, он будет полностью представлять то, что вы читаете в:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main() {
char firstChar = 0xff; // force it so you *know* it changes.
int fdInput = open("file.txt", O_RDONLY);
if (fdInput == -1) {
perror("file");
_exit(1);
}
read(fdInput, amp;firstChar, 1);
printf("Taille du nom de fichier : %dn", firstChar); // prints 97
close(fdInput);
}