Почему getw возвращает -1 при попытке прочитать символ? - PullRequest
16 голосов
/ 11 мая 2019

Я надеялся, что увижу результат 65, поскольку 65 - это значение ASCII для A.

Почему я получаю -1 вместо?

#include <stdio.h>

int main()
{
    FILE *fp;
    fp=fopen("first.txt","w");
    putc('A',fp);
    fclose(fp);
    fp=fopen("first.txt","r");
    int x=getw(fp);
    printf("%d\n",x);

    return 0;
}

Ответы [ 3 ]

16 голосов
/ 11 мая 2019

Вы записываете в файл один байт, но затем пытаетесь прочитать из него sizeof(int) байт.getw() возвращает EOF из-за этого, а значение EOF равно -1.

По этой причине при использовании getw() вы должны проверить дескриптор файла, используя ferror(), чтобы иметь возможностьчтобы узнать, является ли возвращенное значение getw() значением, прочитанным из файла, или кодом ошибки.

Или, что еще лучше, используйте fread() для чтения из файлов.getw() - это старая функция для совместимости со старым кодом.Или используйте getc() или fgetc() вместо этого, который всегда возвращает unsigned char приведение к int и, таким образом, EOF можно легко различить:

int x = getc(fp);
if (x == EOF) {
    fputs("Error reading from file.\n", stderr);
} else {
    printf("%d\n",x);
}
6 голосов
/ 11 мая 2019

О, я вижу, у вас тут проблема с "w", просто измените "w" на "c" и улыбнитесь.На самом деле, вы на правильном пути.Просто измените getw () на getc ().

Вывод равен -1, потому что вы используете функцию getw () для чтения файла .txt, содержащего символ, тогда как функция getw () читает целое число из файла,Поэтому правильная функция - getc (), потому что в вашем файле .txt есть char.Функция getc () читает символ из файла.

Копирует и вставляет еще быстрее:

#include <stdio.h>

int main()
{
    FILE *fp;
    fp=fopen("first.txt","w");
    putc('A',fp);
    fclose(fp);
    fp=fopen("first.txt","r");
    int x=getc(fp);
    printf("%d\n",x);

    return 0;
}

Это вывело бы 65.

3 голосов
/ 11 мая 2019

Вы получаете -1, потому что getw() читает следующее слово из потока (размер слова равен размеру int и может варьироваться от машины к машине), но в вашем случае при попытке при чтении слова из файла встречается EOF, и для конца потока устанавливается индикатор конца файла, а getw() возвращает EOF. Обратите внимание, что EOF является макросом, который расширяется до целочисленного константного выражения с типом int и зависящим от реализации отрицательным значением, но очень часто -1.

Вы должны использовать putw() для записи файла, если вы хотите использовать getw() для чтения файла.

Чтобы показать разницу в файле при использовании putc() и putw() для записи файла:

При использовании putc():

putc('A',fp);

проверить размер файла:

# ls -lh first.txt
-rw-r--r--  1 <owner>  <group>     1B May 11 18:02 first.txt
                                   ^
                                   |
                                size: 1 byte

При использовании putw():

putw('A', fp);   // the first parameter type of putw() is int and the character will implicitly promoted to int

проверить размер файла:

# ls -lh first.txt
-rw-r--r--  1 <owner>  <group>     4B May 11 18:00 first.txt
                                   ^
                                   |
                                size: 4 bytes

При использовании putw():

#include <stdio.h>

int main(void) {
    FILE *fp;

    fp = fopen("first.txt", "w");
    if (fp == NULL) {
        fprintf (stderr, "Failed to open file for write");
        return -1;
    }

    putw('A', fp); // add the error handling for putw()
    fclose(fp);

    fp = fopen("first.txt", "r");
    if (fp == NULL) {
        fprintf (stderr, "Failed to open file for read");
        return -1;
    }

    int x = getw(fp);

    if (feof(fp)) {
        printf ("End of file reached\n");
    }
    else if (ferror(fp)) {
        printf ("Error occurred\n");
    }
    else {
        printf ("%d\n", x);
    }

    return 0;
}

Выход:

# ./a.out
65
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...