Язык Си. Лабораторные работы / Примеры отчетов / Lab9
.docx
Лабораторная работа №9
РАБОТА СО СТРОКАМИ
Студент гр. ИКПИ-81
Коваленко Л. А.
А. Постановка задачи
Имеется текст, состоящий из n (n<=20) строк, который вводится с клавиатуры. Длина каждой строки не превышает 128 символов. В каждой строке содержится не менее двух слов. Количество слов в строке не более 20. Отдельные слова отделяются друг от друга одним или более пробелами. Необходимо выполнить заданную обработку введенного текста — поменять местами первое и второе слово в каждой строке. Вывод результатов обработки текста выполняется после завершения его ввода. При обработке необходимо учитывать возможность наличия во введенной строке ведущих и завершающих пробелов. Количество пробелов во введенном и обработанном тексте может не совпадать. При разработке программы для решения поставленной задачи необходимо использовать функции в максимальной степени.
Лабораторная работа выполняется в виде одного файла, содержащего функции для работы с массивами и основную функцию main().
Б. Разработка алгоритма
Алгоритм решения задачи следующий:
-
Ввод n (количества строк).
-
Ввод символов (129 символов, т. е. 128 и 1 нулевой символ) в двумерный массив (с помощью функции).
-
Обработка символов двумерного массива (с помощью функции).
-
Нормализация строки (удаление пробелов с двух сторон, нормализация пробелов в середине до одного; отдельная функция).
-
Поиск первых двух пробелов строки для определения позиции первого и второго слов.
-
Задание буфера для первого слова (использование выделения блока памяти при помощи библиотечной функции malloc()).
-
Замена первого слова вторым (библ. функция strncpy()).
-
Замена второго слова первым (буфером; библ. функция strncpy()).
-
-
Вывод полученных строк (с помощью функции).
Входные данные состоят из величины n (количество строк) и n строк. Значение n вводится в основной части программы. Ввод, вывод и обработка массива осуществляется при помощи функций в заголовочном файле funcLib.h.
В. Таблица идентификаторов
N |
Обозначение в задаче |
Идентификатор |
Назначение |
1 |
n |
n |
Входные данные |
2 |
– |
**str |
Указатель на массив указателей (двумерный массив строк), входные и выходные данные |
3 |
Длина каждой строки |
LEN |
Константа, равная длине строки (129 символов) |
4 |
– |
i |
Промежуточные данные пользовательских функций |
5 |
– |
m |
|
6 |
– |
j |
|
7 |
– |
a |
|
8 |
– |
b |
|
9 |
– |
p1 |
|
10 |
– |
p2 |
|
11 |
– |
buffer |
0
Начало
Ввод
n 1
2
3
4
Останов 5
1
2
Нет Да Нет
&&
(a[i-1]<>' ') Да Нет Да Нет 1 2 3 4 5 6 7 8 9
(a[i][j]=='
') || (a[i][j]=='\0') Да Нет 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Д. Контрольный расчет
Контрольный набор с , ; . В строке не менее двух слов.
Результаты вычислений приведены ниже в таблице вычислений.
Назначение набора данных |
Набор данных |
Результаты вычислений |
||
n |
Строка |
Ручные |
Машинные |
|
Контрольный набор |
1 |
slovo1 slovo2 3 |
slovo2 slovo1 3 |
slovo2 slovo1 3 |
2 |
aaa bbbb cd |
bbbb aaa cd |
bbbb aaa cd |
|
r l k s |
l r k s |
l r k s |
||
3 |
__sf_dkp_45 |
dkp_sf_45 |
dkp_sf_45 |
|
_nbr___ctrl_s |
ctrl_nbr_s |
ctrl_nbr_s |
||
___rschr__pp |
pp_rschr |
pp_rschr |
Е. Программа на языке Си
/* Файл Lab9.c */
// Стандарт языка СИ: "ISO C99"
// Компилятор: "TDM-GCC (MinGW) 4.9.2"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "funcLib.h" // своя библиотека
// Длина строки: 128 символов + 1 нулевой символ
#define LEN 129
/*
Лабораторная работа 9
РАБОТА СО СТРОКАМИ
Студент гр. ИКПИ-81
Коваленко Л. А.
*/
int main() {
// Объявление i, n и указателя на массив указателей
int i, n;
char **str = NULL;
// Ввод количества строк
printf("Input n: ");
scanf("%d", &n);
// Выделение памяти для динамического двумерного массива
// n – количество строк, LEN – количество символов в строке
// if для проверки на наличие ошибок при выделении блока памяти
if (!(str = (char **)malloc(n * sizeof(char*)))) {
printf("Error 1: Can't allocate memory for rows");
getchar();
return 1;
}
for (i = 0; i < n; i++)
if (!(str[i] = (char *)malloc(LEN * sizeof(char)))) {
printf("Error 2: Can't allocate memory for cols");
getchar();
return 2;
}
// Ввод двумерного массива
printf("Input %d string (%d chars):\n", n, LEN);
IStrTwoDim(n, str);
// Обработка двумерного массива
RmkTwoDim(n, LEN, str);
// Вывод двумерного массива
printf("\nResult:\n");
OStrTwoDim(n, str);
// Освобождение динамического двумерного массива
free(str);
return 0;
}
/* Файл funcLib.h */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/// [ОСНОВНОЕ] Функция ввода двумерного массива
void IStrTwoDim(int n, char **a) {
int i;
for (i = 0; i < n; i++) {
fgets(a[i], j, stdin);
scanf("%[^\n]s", a[i]);
}
}
/// [ОСНОВНОЕ] Функция вывода двумерного массива
void OStrTwoDim(int n, char **a) {
int i;
for (i = 0; i < n; i++)
puts(a[i]);
}
/// [ДОПОЛНИТЕЛЬНО] Функция нормализации текста в строке
/// — Удаляет пробелы слева и справа.
/// — Нормализует пробелы внутри текста до одного.
/// Строка a — исходный массив, результат записывается в b.
/// n — количество символов в строке.
void StrNormalText(int n, const char *a, char *b){
int i = 0, m = 0, j = 0;
for (i; i < n; i++) {
if (j == 0) {
if (a[i] != ' ') {
b[m++] = a[i];
j = 1;
}
}
else {
if ((a[i] == ' ') && (a[i-1] != ' '))
b[m++] = a[i];
else if (a[i] != ' ')
b[m++] = a[i];
}
}
if (b[m-1] == ' ') b[m-1] = '\0';
}
/// [ОСНОВНОЕ] Функция обработки двумерного массива строк
/// Возвращает 0, если все прошло успешно
/// Возращает -1, если произошла ошибка при выделении памяти под буфер
int RmkTwoDim(int n, int m, char **a){
int i, j, p1, p2;
char *buffer; // Буфер для первого слова
for (i = 0; i < n; i++) {
p1 = 0; p2 = 0;
// Вызов функции нормализации текста в строке
StrNormalText(m, a[i], a[i]);
// Поиск первых двух пробелов в строке
for (j = 0; j < m; j++)
if ((a[i][j] == ' ') || (a[i][j] == '\0'))
if (p1 == 0)
p1 = j;
else if (p2 == 0) {
p2 = j;
break;
}
// Выделение памяти для буфера
if (!(buffer = (char *)malloc((p1+1) * sizeof(char))))
return -1;
// Копирование первого слова в буфер
strncpy(buffer, a[i], p1);
buffer[p1] = '\0';
// Копирование второго слова на место первого
strncpy(*(a+i), *(a+i)+(p1+1), p2-p1-1);
a[i][p2-p1-1] = ' ';
// Копирование буфера на место второго слова
strncpy(*(a+i)+(p2-p1), buffer, p1);
// Освобождение буфера
free(buffer);
}
return 0;
}
Ж. Выводы
Тот факт, что результаты контрольных расчетов, выполненных вручную, достаточно совпадают с результатами контрольных расчетов, выполненных на ЭВМ, свидетельствуют о том, что программа составлена правильно.