Skip to content

Запись и считывание символов и строк. Часть 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

Опубликовано вСи

2 комментария

  1. Яна Яна

    Здравствуйте! Пытаюсь разобраться с задачей 2. Но компилятор выдает ошибку ISO C90 forbids mixed declarations and code. Подскажите, пожалуйста, в чем причина?

    • Nikitas Nikitas

      Здравствуйте! Проблема связана со стандартами объявления переменных. Если просто скачать и запустить на штатном gcc проблем быть не должно:
      ➜ echo «Hello» > file.txt
      ➜ gcc —version
      gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
      ➜ gcc 4-2.c
      ➜ ./a.out
      Hello

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

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