Ftell для текстовых файлов - PullRequest
       32

Ftell для текстовых файлов

1 голос
/ 24 января 2020

Я использую эту маленькую программу, чтобы понять, как работает ftell. Я создал текстовый файл, и я набрал «15» и ниже, во второй строке «нет». Итак, я ожидал, что он напечатает 0, затем после того, как он прочитает 15, напечатает 2, а затем, поскольку нет во второй строке, то есть я оставил несколько «доступных мест» в первой строке, которые я мог бы заполнить большим количеством символов я бы ожидал, что он напечатает определенно большее число, чем 7 (что он и напечатал) ПОЧЕМУ?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    int x;
    char box[10];

    fp = fopen("test.txt", "r");

    printf("%ld", ftell(fp));

    fscanf(fp,"%d",&x );
    printf("\n%ld", ftell(fp));

    fscanf(fp, "%s", box);
    printf("\n%ld\n", ftell(fp));
}

вывод: 0 2 7

Ответы [ 2 ]

4 голосов
/ 24 января 2020

Нет ничего похожего на доступных слотов в текстовом файле (*). Это просто последовательность символов, некоторые из которых затем интерпретируются как конец строки (обычно \r, \n или \r\n). Таким образом, ваш текстовый файл должен содержать следующие символы (при условии DOS / Windows EOL):

1 5 \r \n n o \r \n

Этот файл должен выводиться для вывода: 0 2 6.

Если у вас 7 как последнее значение, вероятно, где-то есть пробел, возможно, в конце первой строки (между 5 и \r).


По крайней мере в обычной ОС текстовые файлы представлены в виде потоки с разделителями строк. Спасибо @JohnBollinger за то, что он заметил, что другие ОС могли иметь текстовые файлы с фиксированной длиной записи

1 голос
/ 24 января 2020

Предполагая, что ваш файл содержит:

"15\r\nno\r\n"

Затем первое преобразование считывается в 1 (поз. 1) и 5 (поз. 2), затем считывается возврат каретки \r (поз. 3), что составляет ungetc() с (снова поз. 2).

Затем читается следующая строка (no) и удаляется \r, что снова толкнул обратно в поток, следовательно, позиция должна быть 6. Чтобы объяснить 7, между 15 и no (например, конечный или ведущий пробел) должен быть какой-то дополнительный пробел.

Так что, вообще говоря, позиция всегда является последним символом, который *scanf() преобразовал. Следующий (не соответствующий) символ должен быть прочитан, но возвращен в поток.

...