Как считать все строки из файла c
Перейти к содержимому

Как считать все строки из файла c

  • автор:

Ввод данных из файла и вывод в файл

До этого при вводе-выводе данных мы работали со стандартными потоками — клавиатурой и монитором. Теперь рассмотрим, как в языке C реализовано получение данных из файлов и запись их туда. Перед тем как выполнять эти операции, надо открыть файл и получить доступ к нему.

В языке программирования C указатель на файл имеет тип FILE и его объявление выглядит так:

FILE *myfile;

С другой стороны, функция fopen() открывает файл по указанному в качестве первого аргумента адресу в режиме чтения («r»), записи («w») или добавления («a») и возвращает в программу указатель на него. Поэтому процесс открытия файла и подключения его к программе выглядит примерно так:

myfile = fopen("hello.txt", "r");

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

При чтении или записи данных в файл обращение к нему осуществляется посредством файлового указателя (в данном случае, myfile).

Если в силу тех или иных причин (нет файла по указанному адресу, запрещен доступ к нему) функция fopen() не может открыть файл, то она возвращает NULL. В реальных программах почти всегда обрабатывают ошибку открытия файла в ветке if , мы же далее опустим это.

Объявление функции fopen() содержится в заголовочном файле stdio.h, поэтому требуется его подключение. Также в stdio.h объявлен тип-структура FILE.

После того, как работа с файлом закончена, принято его закрывать, чтобы освободить буфер от данных и по другим причинам. Это особенно важно, если после работы с файлом программа продолжает выполняться. Разрыв связи между внешним файлом и указателем на него из программы выполняется с помощью функции fclose() . В качестве параметра ей передается указатель на файл:

fclose(myfile);

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

Чтение из текстового файла и запись в него

fscanf()

Функция fscanf() аналогична по смыслу функции scanf() , но в отличии от нее осуществляет форматированный ввод из файла, а не стандартного потока ввода. Функция fscanf() принимает параметры: файловый указатель, строку формата, адреса областей памяти для записи данных:

fscanf(myfile, "%s%d", str, &a); 

Возвращает количество удачно считанных данных или EOF. Пробелы, символы перехода на новую строку учитываются как разделители данных.

Допустим, у нас есть файл содержащий такое описание объектов:

apples 10 23.4 bananas 5 25.0 bread 1 10.3

Тогда, чтобы считать эти данные, мы можем написать такую программу:

#include int main () { FILE *file; struct food { char name[20]; unsigned qty; float price; }; struct food shop[10]; char i=0; file = fopen("fscanf.txt", "r"); while (fscanf(file, "%s%u%f", shop[i].name, &(shop[i].qty), &(shop[i].price)) != EOF) { printf("%s %u %.2f\n", shop[i].name, shop[i].qty, shop[i].price); i++; } }

В данном случае объявляется структура и массив структур. Каждая строка из файла соответствует одному элементу массива; элемент массива представляет собой структуру, содержащую строковое и два числовых поля. За одну итерацию цикл считывает одну строку. Когда встречается конец файла fscanf() возвращает значение EOF и цикл завершается.

fgets()

Функция fgets() аналогична функции gets() и осуществляет построчный ввод из файла. Один вызов fgets() позволят прочитать одну строку. При этом можно прочитать не всю строку, а лишь ее часть от начала. Параметры fgets() выглядят таким образом:

fgets(массив_символов, количество_считываемых_символов, указатель_на_файл)
fgets(str, 50, myfile)

Такой вызов функции прочитает из файла, связанного с указателем myfile, одну строку текста полностью, если ее длина меньше 50 символов с учетом символа ‘\n’, который функция также сохранит в массиве. Последним (50-ым) элементом массива str будет символ ‘\0’, добавленный fgets() . Если строка окажется длиннее, то функция прочитает 49 символов и в конце запишет ‘\0’. В таком случае ‘\n’ в считанной строке содержаться не будет.

#include #define N 80 main () { FILE *file; char arr[N]; file = fopen("fscanf.txt", "r"); while (fgets(arr, N, file) != NULL) printf("%s", arr); printf("\n"); fclose(file); }

В этой программе в отличие от предыдущей данные считываются строка за строкой в массив arr. Когда считывается следующая строка, предыдущая теряется. Функция fgets() возвращает NULL в случае, если не может прочитать следующую строку.

getc() или fgetc()

Функция getc() или fgetc() (работает и то и другое) позволяет получить из файла очередной один символ.

#include #define N 80 int main () { FILE *file; char arr[N]; int i; file = fopen("fscanf.txt", "r"); while ((arr[i] = fgetc(file)) != EOF) { if (arr[i] == '\n') { arr[i] = '\0'; printf("%s\n",arr); i = 0; } else i++; } arr[i] = '\0'; printf("%s\n",arr); fclose(file); }

Приведенный в качестве примера код выводит данные из файла на экран.

Запись в текстовый файл

Также как и ввод, вывод в файл может быть различным.

  • Форматированный вывод. Функция fprintf ( файловый_указатель, строка_формата, переменные ) .
  • Посточный вывод. Функция fputs ( строка, файловый_указатель ) .
  • Посимвольный вывод. Функция fputc() или putc( символ, файловый_указатель ) .

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

Запись в каждую строку файла полей одной структуры:

#include int main () { FILE *file; struct food { char name[20]; unsigned qty; float price; }; struct food shop[10]; char i=0; file = fopen("fprintf.txt", "w"); while (scanf("%s%u%f", shop[i].name, &(shop[i].qty), &(shop[i].price)) != EOF) { fprintf(file, "%s %u %.2f\n", shop[i].name, shop[i].qty, shop[i].price); i++; } fclose(file); }

Построчный вывод в файл ( fputs() , в отличие от puts() сама не помещает в конце строки ‘\n’):

while (gets(arr) != NULL) { fputs(arr, file); fputs("\n", file); }

Пример посимвольного вывода:

while ((i = getchar()) != EOF) putc(i, file);

Чтение из двоичного файла и запись в него

С файлом можно работать не как с последовательностью символов, а как с последовательностью байтов. В принципе, с нетекстовыми файлами работать по-другому не возможно. Однако так можно читать и писать и в текстовые файлы. Преимущество такого способа доступа к файлу заключается в скорости чтения-записи: за одно обращение можно считать/записать существенный блок информации.

При открытии файла для двоичного доступа, вторым параметром функции fopen() является строка «rb» или «wb».

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

Функции fread() и fwrite() принимают в качестве параметров:

  1. адрес области памяти, куда данные записываются или откуда считываются,
  2. размер одного данного какого-либо типа,
  3. количество считываемых данных указанного размера,
  4. файловый указатель.

Эти функции возвращают количество успешно прочитанных или записанных данных. Т.е. можно «заказать» считывание 50 элементов данных, а получить только 10. Ошибки при этом не возникнет.

Пример использования функций fread() и fwrite() :

#include #include int main () { FILE *file; char shelf1[50], shelf2[100]; int n, m; file = fopen("shelf1.txt", "rb"); n=fread(shelf1, sizeof(char), 50, file); fclose(file); file = fopen("shelf2.txt", "rb"); m=fread(shelf2, sizeof(char), 50, file); fclose(file); shelf1[n] = '\0'; shelf2[m] = '\n'; shelf2[m+1] = '\0'; file = fopen("shop.txt", "wb"); fwrite(strcat(shelf2,shelf1), sizeof(char), n+m, file); fclose(file); }

Здесь осуществляется попытка чтения из первого файла 50-ти символов. В n сохраняется количество реально считанных символов. Значение n может быть равно 50 или меньше. Данные помещаются в строку. То же самое происходит со вторым файлом. Далее первая строка присоединяется ко второй, и данные сбрасываются в третий файл.

  1. Напишите программу, которая запрашивает у пользователя имя (адрес) текстового файла, далее открывает его и считает в нем количество символов и строк.
  2. Напишите программу, которая записывает в файл данные, полученные из другого файла и так или иначе измененные перед записью. Каждая строка данных, полученная из файла, должна помещаться в структуру.

Курс с решением части задач:
pdf-версия

Чтение файла построчно

Нужно открыть файл и прочитать его построчно, то есть взять первую строку занести её в переменную, проделать с ней определённые операции, потом брать вторую и т.д.

Отслеживать
9,325 6 6 золотых знаков 23 23 серебряных знака 57 57 бронзовых знаков
задан 6 окт 2013 в 6:48
Никола Кривошея Никола Кривошея
1,487 4 4 золотых знака 34 34 серебряных знака 71 71 бронзовый знак
Смотрите метод getline() Например: std::string name; std::getline (std::cin,name);
6 окт 2013 в 6:56

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

вот код не вырванный из контекста

#include #include // подключаем строки #include // подключаем файлы using namespace std; // используем стандартное пространство имен int main() < string s; // сюда будем класть считанные строки ifstream file("C:\\PriceList.dat"); // файл из которого читаем (для линукс путь будет выглядеть по другому) while(getline(file, s))< // пока не достигнут конец файла класть очередную строку в переменную (s) cout file.close(); // обязательно закрываем файл что бы не повредить его return 0; > 

Отслеживать
ответ дан 1 авг 2015 в 11:01
9,971 14 14 золотых знаков 53 53 серебряных знака 117 117 бронзовых знаков

Ээээ. А вы уверены насчёт eof ? Если я не ошибаюсь, eof для istream ‘ов возвращает true не когда поток находится в конце файла, а когда поток находится в конце файла, и предыдущая попытка чтения из-за этого завершилась неудачно.

1 авг 2015 в 11:08

если честно я сам не уверен, насколько я понимаю при считывании очередной строки указатель сдвигается на конец этой строки. давно не кодил но пример отлично отрабатывает без ошибок. а вот сдесь cplusplus.com/forum/beginner/11304 тоже похожий код указан

Как считать все строки из файла c

— tags: си, прога — # Чтение из файлов в си Как читать файлы в C и обработать все ошибки? ## `fgetc` «`c if (fgetc(f) == ‘#’) < while (fgetc(f) != '\n') <>> «` Вот тут мы скипаем по одному байту, пока не наткнёмся на `\n`. Его тоже съедим и поедем дальше. Ошибки все игнорируются. Это. страшно. Какие они могут быть? — `EOF` — страшная аббриевиатура означает `end of file`. `fgetc` возвращает не `char`, а `int`. Потому что она может вернуть и `EOF`. Это будет означать, что файл закончился. — Другие ошибки чтения. Жёсткий диск умер внезапно, прочесть не смогли, система кидает ошибку, потоп, пожар, всё что ни есть на свете может разные ошибки заставить вернуть `fgetc`. В общем, если какая-то ошибка есть, получим вместо символа `EOF`. Это надо проверить. Раздуваем код выше: «`c int skip_comment_if_any(FILE *f) < int ch = fgetc(f); if (ch == EOF) < return -1; >if (ch != ‘#’) < // коммента нет, всё ок return 0; >while (1) < ch = fgetc(f); if (ch == EOF) < // файл скончался преждевременно return -1; >if (ch == ‘\n’) < // кончилась строка return 0; >> > «` Вроде такого. Прочесть что-то из файла — полбеды. Другая половина — обработать все ошибки. В си вынуждены мы страдать. Чтобы страдать меньше, всё растаскиваем по функциям. Скипать коммент — функция. Прочесть хедер в файле — функция. Раны (от слова run) из самих данных поля скушать — функция. ## `fgets` Итак, это был `fgetc`. Заменим `c` на `s`: `fgets` кушает несколько байт из файла и сохраняет их в буфер. Отличие от `fread`: в конец пихается `\0`. Удобно. «`c char *str = calloc(10, sizeof(char)); fgets(str, 10, f); printf(«%s», str); «` Она прочтёт **девять** байт, а десятый будет `\0`. Или не десятый, если не хватит в файле байт. Какие тут ошибки? Ну да всё те же самые. Если будет ошибка, `fgets` вернёт `NULL` для разнообразия. «`c char *str = calloc(10, sizeof(char)); if (fgets(str, 10, f) == NULL) < // ошибка чтения return -1; >printf(«%s», str); «` Так-то лучше. ## `fscanf` Есть ещё одна полезная функция для чтения из файла. Это уже formatted input/output называется. Для файлов `fscanf` нас интересует. Это. вариант для ленивых, на самом деле. Как известно, `fscanf` делает всё на свете: и числа читает, и строки, и байты. За удобство платим, конечно. Ошибки обрабатывать сложно. Смотрим сюда. В файле записано `test`. «`c int count = 0; fscanf(f, «%d», &count); print(count); «` Я без понятия, что этот код выведет, потому что в файле даже цифры нет. Это плохо. Нам надо будет парсить RLE — это, если забыть про комменты и хедер, набор данных рода `<число>`. Число — это количество символов «, которые мы схлопнули здесь. «` 2ob4o «` Это закодирована строка `ooboooo`. Вот мы начали писать функцию `read_run`. «`c int read_run(FILE *f, /* какие-то ещё параметры */) < int count = 0; fscanf(f, "%d", &count); // Про остальное пока забудем. >«` Мы ленивы, юзаем `fscanf`. Попробуем поломать нашу наивную функцию. Дадим ей `test`. Будет ошибка. Узнать об ошибке мы можем, если посмотрим, что вернёт `fscanf`. Она плюётся числом — количеством **скушанных процентиков**. В коде выше с `test` вернётся `0`, то есть числа там не прочёл `fscanf`. Хорошо: «`c int count = 0; // В строке формата у нас один процент, // так что fscanf должен вернуть 1. if (fscanf(f, «%d», &count) != 1) < // Сисла нет, дефолтимся в 1. count = 1; >«` Почему `1`? Ну, единичный символ в RLE пишет без числа. Просто `o` кодирует просто `o`, без лишних заворотов. То есть один символ. Замечательно. `fscanf` может ещё заменить `fgetc` волшебным заклинанием `%c`: «`c // Продолжаем: char ch; if (fscanf(f, «%c», &ch) != 1) < // Что-то символ не смогли прочесть. // Похоже, что файл скончался. return -1; >«` Наверное, это удобнее. Теперь мы прочли число и символ, можем обрабатывать его. А все ли ошибки учли? Ноп. Пусть в файле лежит `-2o`. Первый `fscanf`, который с `%d`, радостно сожрёт `-2`. Ну, отрицательный размер — это странно. Вернёмся к коду тому и добавим: «`c int count = 0; if (fscanf(f, «%d», &count) != 1) < // Числа нет, дефолтимся в 1. count = 1; >if (count < 0) < // Отрицательное число — ошибка. return -1; >«` Тяк, всё обработали? — [x] Отрицательные числа — [x] Положительные числа — [x] Ноль — [ ] Слишком большие числа А, не, погодите. Пусть в файле лежит `123456789012345678901234567890`. В `int` такое число не влезет. Что вернёт `fscanf`? Ща погуглим. . Гугл что-то молчит, тогда проверим сами: «`c #include int main() < int number; printf("Enter a number: "); scanf("%d", &number); printf("Your input: %d\n", number); return 0; >«` Компилируем и запускаем: «` $ gcc main.c -o ./prog $ ./prog Enter a number: 1234567898012345678901234567890 Your input: -1 «` Нехорошо, нехорошо. Окей, короче, я всё это говорил к тому, что `fscanf` в жизни мы сможем юзать только для чтения одного байта, наверное. Потому что нельзя нормально обработать ошибки. ## Как прочесть число Забудем про `fscanf` окончательно и будем сами красиво парсить числа. Немного вводных данных. В « есть функция под именем [`strtoull`](https://en.cppreference.com/w/c/string/byte/strtoul). Она берёт строку и преобразует её в число. Пытается, как минимум. Если не может, то функция не взрывается. Значит, можно использовать. «`c #include // Возвращаем int — это код ошибки. // Сам результат будет в *result. int read_count(FILE *f, unsigned long long *result) < // 1. В unsigned long long влезет до 18446744073709551615. Это 20 цифр. // Поэтому создаём буфер на 21 символ, которые мы будем читать. // двадцать первый — это `\0`. char str[21] = ; size_t len = 0; bool significant_digits_started = false; // 2. Читаем по одной цифре, пока число не закончится. for (int i = 0; i < 20; ++i) < int ch = fgetc(f); if (ch != EOF && !isdigit(ch)) < // Мы сожрали один байт, и это не цифра. // Вернём байт назад. // ungetc также может завершиться с ошибкой. if (ungetc(ch, f) == EOF) < return -1; >> if (ch == EOF || !isdigit(ch)) < // Не цифра или конец файла: завершаем строку, брякаемся. str[i] = '\0'; break; >// Вот этот иф будет скипать нули в начале числа. if (ch != ‘0’ || significant_digits_started) < str[i] = (char) ch; len++; >> // 3. Вызываем strtoull if (len == 0) < // Если цифру не встретили, выходим. return -2; >char *end; *result = strtoull(str, &end, 10); // end после вызова указывает на последний байт, который strtoull обработал. // Точнее, на следующий за последним обработанным байт. // Если он завершится посередине, не на конце строки, то он столкнулся с ошибкой. if (end != &str[len]) < // Ошибка. 111111 return -3; >// 4. Ошибок нет. Число в *result. return 0; > «` Фух. Сколько раз я мог здесь прострелить свою бедную ногу, боюсь считать. А я это ещё не дебажил. Не буду лишать веселья этим заниматься. А, да, к слову. `ungetc` там есть — это значит взять символ и засунуть его обратно в файл. Если прочесть его позже, то мы его получим назад. Такое можно сделать только один раз. Сразу 10 символов обратно не запихаем, к сожалению. ## Итог Итак, в конце этого документа надо что-то заключительное рассказать. Ну, мы узнали, что `fgetc` нужен, чтобы читать один байт. `fgets` нужен, чтобы прочесть сразу несколько. `fscanf` нужен почти никогда, потому что он игнорирует ошибки. Только для прототипов хороша функция эта. Наконец, есть код, которым можно прочесть одно число из файла. И в нём узнали про `strtoull` и `ungetc`. ## Конец (файла). Это как постскриптум. Не всегда конец файла — это ошибка. Например, если данные закончились, то конец файла закономерен. Нужно тщательно подумать в коде о том, когда `EOF` ошибка, а когда нет. По-моему, я писал выше где-то, что `EOF` на самом деле возвращается при всём подряд: конце файла, другой ошибке чтения. Поэтому нужно знать ещё 2 функции для полного счастья. — `feof(f)` — кончился ли файл. — `ferror(f)` — встретилась ли какая-то другая ошибка. Жонглируя этими функциями, мы можем правильно обработать ошибки. «`c while (true) < unsigned long long count = 0; int status = read_count(file, &count); if (status == -1) < // EOF или ошибка чтения: и то, и другое для нас ошибка, // потому что файлу рано кончаться здесь return -1; >else if (status == -2) < // Не встретили цифру: будем считать, что дали 1 count = 1; >else if (status == -3) < // Слишком огромное число. Выходим. return -1; >if (count == 0) < // Дали `0o` какой-нибудь. Это невалидно. Длины больше нуля должны быть. return -1; >int ch = fgetc(file); if (ch == EOF) < if (status == -2 && feof(file)) < // Не встретили цифру, но дошли до EOF. // Файл, то бишь, кончился. // Значит, всё кончилось, выходим. Это не ошибка. return 0; >// Иначе, значит, ошибка. return -1; > // Теперь можно что-то делать с count и ch. > «` Вот заготовка для чтения данных поля. Чтобы понять, что файл кончился по-хорошему, используем `feof`. Теперь точно всё.

Last changed by
The first at being the last
Add a comment

Read more

Java 1

Конспект по первому семинару по Джаве. Как вообще запускаются программы на Java? ИЕ просил перед парой установить JDK, чтобы радотали команды javac, javap, java. javac компилирует .java в .class, синтаксис (базовый) такой: javac Main.java После этой операции полявляется файл Main.class javap — дизассемблер для файлов .class, синтаксис:

Задачи с зачёта (2020-12-10, четверг)

АХТУНГ: копипаст кода отсюда тождественно равно получению пермабана. Семинарист мой код спалит моментально — быстрее, чем свет до него дойдёт, от листочка отразившись. Никто так не упарывается с красотой и декомпозицией. Весь код даётся только в образовательных целях, чтобы понять, куда рыть. Алгоритмы вы будете писать на нелинованных листочках A4 ручкой, простыню убьётесь копировать. ДИСКЛЕЙМЕР: Ответы могут быть несущественно, заметно, разительно или полностью и в корне неверными. Если ошибки есть, то виноваты все, кроме меня. Но можете написать, и я исправлю. Задача 1. Область видимости и время жизни Классифицируйте виды переменных по области видимости и по времени жизни. Приведите примеры. Времена жизни переменных

Запись и считывание символов и строк. Часть 1

Запись и считывание символов и строк в Си

Доброго времени суток! Сегодня мы поговорим о строках и символах в Си, и о том, как они передаются в файл. Сначала немного теории. До этого момента мы уже разбирали, как передавать переменную на вывод с помощью спецификаторов формата (%d, %c и т.д.). А также рассматривали различные методы открытия файлов для записи и чтения. Теперь давайте обобщим все варианты открытия файла и, что значит каждое обозначение.

Режимы чтения и записи файлов

В Си, для открытия файла, используется команда fopen(), в аргументах которого записывается имя файла и обозначение режима записи: r (r+) — файл открывается для чтения (чтения и записи); w (w+) — открывается пустой файл для записи (чтения и записи). Если файл с таким именем существует, он стирается; a (а+) — файл открывается для дополнения в конец (чтения и дополнения). Как пример: file = fopen(«file.tx) .

Спецификаторы

Повторим основную часть для функции scanf():
%c Читает одиночные символы
%d Читает десятичное число
%f Читает число с плавающей запятой
%s Читает строку Другие функции считывания разберём уже на примерах.

Задачи на запись и считывание строк и символов в Си

Теперь, когда мы всё обобщили приступим к задачам на символы и строки.

Записать в текстовый файл на разных строках 5 слов и 3 числа, закрыть его, а потом дописать туда еще 2 символа.
Данная несложная задача проверяет нас на знание тех самых режимов открытия файлов, о которых мы говорили ранее.

#include #include int main(void)  FILE*file; file = fopen(«file.txt»,»w+»); char str[200]; int ch1, ch2, ch3; gets(str); scanf(«%d%d%, & ch1,& ch2,& ch3); 

Для работы со строками в Си предусмотрены разнообразные библиотеки с различными функциями. В стандартной библиотеке список таких функций скромен, но в большинстве случаев этого достаточно. gets() аналог функции scanf(), однако, работает он только со строкой. Записывает в указанный аргумент сканируемую им строку из консоли ввода в формате символов. На самом деле и обычные строки следует воспринимать как обычные одномерные массивы с форматом char. Также следует учесть, что размер массива (у нас char str[200]) должен быть не меньше чем строка, а лучше больше.

fputs(str, file); fprintf(file,"\n%d, %d, %d", ch1,ch2,ch3); fclose(file); 

Произведена запись в файл считанных с консоли строки и цифр. И закрыли файл. ВСЕГДА закрывайте файл после открытия. иначе это может повлиять на работоспособность вашего компьютера.

file = fopen("file.txt","a+"); char sym1 = 'R', sym2 = 'T'; fprintf(file, " \n %c , %c ", sym1, sym2); fclose(file); return EXIT_SUCCESS; > 

Идём по заданию и снова открываем файл. Обращаю внимание на режим открытия файла («a+»), записываем туда 2 символа. И закрываем файл. Создать вручную англоязычный текстовый файл небольшого объема. Прочитать файл посимвольно и вывести на экран все символы из файла. Пропустив строку, вывести на экран первую и последнюю букву каждой строки в файле. Так как предстоит более сложная работа со строками, сразу подключим библиотеку string.h

#include stdio.h> #include stdlib.h> #include string.h> #define N 200 int main(void)  int i = 0; FILE*file; file = fopen("file.txt", "r"); char sym[N], c = 0; while( (c = fgetc(file)) != EOF) printf("%c", c); > 

После открытия файла в режиме чтения и инициализации переменных, идёт код, который пригодится вам в будущем. Вывод на экран файла посимвольно! В условии к while указано «пока сканированный символ не означает конец файла». EOF — символ известный в С++ как «\0», означает конец файла.

 fclose(file); printf("\n"); file = fopen("file.txt", "r"); while( !feof(file)) fscanf(file,"%s",sym); i = (strlen(sym)); printf("%c %c ", sym[0], sym[i-1]); > fclose(file); return EXIT_SUCCESS; > 

Условие, используемое при while, такое же как и в предыдущей статье, однако имеет более короткую форму. Функция strlen() из библиотеки string.h позволяет определить длину строки. И представив, что строка — одномерный массив, обратимся к конкретным символам через индекс. Создать вручную англоязычный текстовый файл небольшого объема. Найти, сколько всего гласных содержится в этом файле. Найти количество гласных в каждой строке файла. Результаты дописать в этот же файл на новой строке.

#include stdio.h> #include stdlib.h> #include string.h> #define N 100 int main(void)  int vse = 0, i = 0, k = 0; FILE*file; file = fopen("file.txt", "r"); char c = 0, temp[N]; while( (c = fgetc(file)) != EOF) if ((c == 'A') || (c == 'a') || (c == 'E') || (c == 'e') || (c == 'I') || (c == 'i') || (c == 'O') || (c == 'o') || (c== 'Q') || (c == 'q') || (c == 'U') || (c == 'u') || (c == 'Y') || (c == 'y')) vse++; > fclose(file); 

Перво-наперво, посчитаем количество гласных во всём файле с помощью счётчика vse.

file = fopen("file.txt", "r"); k = 0; while (!feof(file)) fgets(temp, N, file); k++; > fclose(file); 

Теперь посчитаем количество строк, чтобы создать одномерный массив с количеством элементов равным количеству строк.

file = fopen("file.txt", "r"); int * kol; int j; kol = (int*)malloc(k * sizeof(int)); for (j = 0; j  k; j++) kol[j] = 0; fgets(temp, N ,file); for (i = 0; i  (strlen(temp)); i++) if ((temp[i] == 'A') || (temp[i] == 'a') || (temp[i] == 'E') || (temp[i] == 'e') || (temp[i] == 'I') || (temp[i] == 'i') || (temp[i] == 'O') || (temp[i] == 'o') || (temp[i] == 'Q') || (temp[i] == 'q') || (temp[i] == 'U') || (temp[i] == 'u') || (temp[i] == 'Y') || (temp[i] == 'y')) kol[j]++; > > fclose(file); 

Не пугайтесь, друзья! Для создания массива, размер которого содержится в переменной, используется команда (int*)malloc(k * sizeof(int)); . Грубо говоря, мы создали динамический массив в Си. В цикле, сканируя по строке с помощью fgets() (где temp — переменная куда записать строку, N — количество символов, file — название файла с которым работаем), находим в строке гласные буквы. В конце записываем значение счётчика в наш массив.

file = fopen("file.txt", "a+"); fprintf(file,"\n"); for (j = 0; j  k; j++) fprintf(file,"%d ", kol[j]); > fprintf(file,"\t vse %d", vse); fclose(file); free(kol); return EXIT_SUCCESS; > 

Теперь просто записываем требующиеся по заданию показания счётчиков в конец файла. Как и в случае закрытия файлов, так и при работе с malloc ВСЕГДА освобождайте память в конце программы с помощью команды free() , где в аргументах имя переменной. На сегодня всё, если остались вопросы, пишите в комментариях. Вот исходники: Все исходники без файлов txt.
Скачать исходники задачи — 1
Скачать исходники задачи — 2
Скачать исходники задачи — 3

Поделиться ссылкой:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *