0

Решаю универскую задачку и встал вопрос: а как считать из файла неизвестное число строк исключительно на языке СИ? На с++ таких проблем нет, а вот как это сделать тут? Например, имею следующий код, который перенаправляет поток ввода из консоли в файл:

#include<stdio.h>
#include<stdlib.h>
#include<string>
int main()
{
    freopen("input.txt", "r", stdin);
    while (true)
    {
        char buff[100];
        scanf("%s", buff);
        if (!strlen(buff))//пытаюсь таким образом определить конец файла
            break;
    }
}

На c++ можно остановить ввод с помощью !file.eof(), есть ли в данном случае сишная альтернатива? Заранее спасибо за ответ!
UPD: нашёл информацию о EOF и в си, но непонятно с чем сравнивать этот макрос в примере, чтоб понять - закончился ли файл.

2 Answers2

1

"На c++ можно остановить ввод с помощью !file.eof()" — не стоит этого делать! См. Правильное использование проверки конца файла

Если уж читаете построчно - просто читайте while(fgets(buff,100,file)) { ... }

Harry
  • 221,325
  • Спасибо! Но я просил именно с использованием freopen и scanf функцией. Во всяком случае, ваш ответ натолкнул меня на решение и кажется получилось! – Максим Герасимов Feb 20 '22 at 15:38
0

Почитав некоторое n-ое число статеек всё-таки нашёл способ, как отловить конец файла, используя EOF и scanf:

#include<stdio.h>
#include<stdlib.h>
#include<string>
int main()
{
    freopen("input.txt", "r", stdin);
    while (true)
    {
        char buff[100];
        if (scanf("%s", buff) == EOF)
            break;
    }
}
  • 1
    Возможно != 1 в данной ситуации лучше чем == EOF. – Stanislav Volodarskiy Feb 20 '22 at 17:03
  • Никогда на используйте голый %s. Всегда добавляйте ширину: %99s в вашем случае. – Stanislav Volodarskiy Feb 20 '22 at 17:03
  • А чем плох голый %s? Извините, если глупые вопросы задаю, просто в СИ новичок. – Максим Герасимов Feb 20 '22 at 19:02
  • Не контролирует запись за пределы буфера. Любая программа с этим оператором уязвима для атаки через входные данные. В лучшем случае она будет падать с ошибкой на длинных словах, в худшем делать что угодно. – Stanislav Volodarskiy Feb 20 '22 at 19:20
  • Если пишете в GNU, то в scanf в формате %s можно использовать optional assignment-allocation character 'm' -- вот так -- "%ms". Это позволяет динамически выделять память и для чтения потока "по словам" можно написать: char *buff; while (scanf("%ms", &buff) == 1) { /* do smth with new word in buff .... */ free(buff);} – avp Feb 20 '22 at 20:04
  • Здравствуйте! Пишу на VS! – Максим Герасимов Feb 21 '22 at 02:54