Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Пояснения к программе и рекомендации по отладке






· Задать константу - максимальную длину строки можно двумя способами:

- записав макрос #definelenmax 41;

- использовав типизированную константу const int lenmax=41.

В программе выбран второй способ, так как макрос – это просто текстовая подстановка на уровне препроцессорной обработки, а типизированная константа обрабатывается компилятором, т.е. дает компилятору информацию о представлении данной величины и может использоваться во время отладки, а потому предпочтительнее [6, с.52].

· Удобно как универсальный вариант использовать ввод-вывод из файлов и программу с параметрами-файлами.

Задавая вместо имени входного/ выходного файла значение параметра con, имеем ввод с клавиатуры/ вывод на экран.

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

 

Результаты выполнения теста (указаны имена конкретных файлов-параметров)

 

 

 

 

Уровень 1

Задача А0.1. Для заданной строки вывести все слова, начинающиеся с заданной буквы, или сообщение, что они отсутствуют.

Оформим функцию. Пусть имена и смысл формальных и фактических параметров совпадают.

Входные данные-параметры:

str[] - массив-строка; как параметр можно передавать без указания границ;

let – заданная буква;

res - указатель на файл вывода (является входным, так как файл открыт вне функции);

Выходные данные: фактически выходом является содержимое файла с заданным указателем, а сам указатель не меняется; поэтому формально выход отсутствует. Заголовок функции (его же используем в качестве прототипа):

void elabor(char str[], char let, FILE* res)

 

Метод

Искомое слово после его обнаружения в строке следует переписать в отдельную строку для вывода. Эта строка - локальная. При описании ее как массива придется задать постоянную границу - ту же, что для исходной строки, так как до выделения слова его размер неизвестен.

Это очень сильное ограничение, такая процедура никуда не годится.

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

Поэтому следует:

- описать слово с помощью указателя на символьную строку;

- определить длину входной строки-параметра;

- выделить память под слово согласно этой длине.

Пусть:

char* word - указатель на строку, куда будет записываться найденное слово;

len - длина входной строки str;

l - номер позиции начала очередного слова в строке str;

i - номер текущего символа строки str;

wy - переменная, фиксирующая наличие искомых слов;

пусть wy =0, если таких слов нет, и 1 - если есть;

j - вспомогательная переменная для переписи символов строки в слово.

Начнем с начала строки: l =0, i =0 и с wy =0.

Пока не кончилась строка:

если str[l]==let, т.е. слово - искомое, то

- зафиксировать, что оно найдено (wy =1);

- переписать его (т.е. последовательность символов до следующего пробела или до конца строки) в word (не забыв добавить нуль-терминатор);

- вывести слово по обр4

иначе

пропустить символы до следующего пробела или конца строки

кесли;

кц

Если искомых слов в строке не найдено, то вывод по обр5.

 

Текст функции: файл str_func.cpp

#include< stdio.h>

#include< string.h>

#include< alloc.h>

void elabor(char str[ ], char let, FILE* res)

{

char* word;

int len, l, wy, i, j;

len=strlen(str); //поиск длины исходной строки

word=(char*)malloc(len+1); //памяти на 1 больше под '\0'

for(wy=0, l=i=0; i< len; l=++i) //l=++i то же, что i=i+1, l=i

{

if(str[l]==let) //слово искомое

{

wy=1; //фиксируем, что нашли, и дальше перепишем в word

for(j=0; str[i]! =' '& & str[i]! ='\0'; j++, i++)

word[j]=str[i];

word[j]='\0'; //добавим нуль-терминатор

fprintf(res, " %s \n", word); //выведем

}

else //слово не то; пропустим его в строке

for(; str[i]! =' '& & str[i]! ='\0'; i++);

}

if(! wy) //ни одного нужного слова так и не нашли

fprintf(res, " отсутствуют \n");

}

 

Текст функции main: str_main.cpp

#include< stdio.h>

#include< string.h>

const int lenmax=41; //типизированная константа - граница массива

void main(int argc, char* argv[])

{

void elabor(char str[], char let, FILE* res); //прототип функции

char let, str[lenmax];

FILE *dat, *res;

int k;

//Открытие файлов с проверкой результатов открытия

if((dat=fopen(argv[1], " r"))==NULL)

printf(" Файл данных не открыт");

if((res=fopen(argv[2], " w"))==NULL)

printf(" Файл результатов не открыт ");

//Вывод заголовков и ввод let

fprintf(res, " Program %s \n", argv[0]);

fscanf(dat, " %c\n", & let);

fprintf(res, " Поиск слов, начинающихся с буквы %c \n", let);

// Построчная обработка файла

k=1;

while(! feof(dat))

{

fgets(str, 41, dat); //неформатированный ввод строки

fprintf(res, " \n %d строка: %s \n", k, str); // форматированный вывод строки

fprintf(res, " Найденные слова: \n");

// А0.1. Обработка строки

elabor(str, let, res);

k++;

}

fclose(dat); fclose(res);

}

 

Входные данные те же.

Результаты: файл string.res

Program K: \TEMP\STR.EXE

Поиск слов, начинающихся с буквы s

 

1 строка: Mr. Priestley has

 

Найденные слова:

отсутствуют

 

2 строка: some students at his house

 

Найденные слова:

some

students

 

3 строка: for lessons.

 

Найденные слова:

отсутствуют

 

4 строка: There are six of them in all

Найденные слова:

six

 

 

Другой метод, тесно связанный с языком

 

Используем функцию char* strtok(char* s1, const char* s2), которая возвращает указатель на группу символов (подстроку) в строке s1, ограниченную с обеих сторон любым из символов строки s2. В строку s1 помещается '\0' вместо разделителя.

Strtok запоминает значение указателя, следующего за последней выделенной группой, и с него начинает работу при следующем вызове. Поэтому во всех вызовах, кроме первого, в качестве s1 надо использовать NULL. При первом вызове функция возвращает указатель на строку s1.

По исчерпании всех групп в строке s1 возвращается NULL.

 

 

Пусть в нашей задаче char* lptr - указатель на начало очередного слова.

 

//вариант с использованием функции strtok.работает с проектом str1.prj

#include< stdio.h>

#include< string.h>

#include< alloc.h>

void elabor(char str[], char let, FILE* res)

{

char* lptr;

int wy;

wy=0;

lptr=strtok(str, " "); //указатель на первую группу символов до ' '

while(lptr! =NULL)

{

if (strchr(lptr, let)==lptr) //если let-первый символ группы,

// то слово искомое

{

wy=1; //фиксируем, что нашли

fprintf(res, " %s \n", lptr); //выведем его

}

lptr=strtok(NULL, " "); //в любом случае ищем следующее

}

 

if(! wy) //ни одного нужного слова так и не нашли

fprintf(res, " отсутствуют \n");

}

 


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.014 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал