Форум программистов, компьютерный форум, киберфорум
Fon Eberkopff
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Лаба 9. Поиск слова в строке.

Запись от Fon Eberkopff размещена 16.11.2016 в 20:11
Показов 3648 Комментарии 4

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**********************************************************************
 * laba9_string.c          15.11.2016
 * 
 * Пользователь вводит с клавиатуры строку с разделителями в виде ' '.
 * Надо выделить слова в предложении. Далее у пользователя запрашивается
 * комбинация символов.
 * Нужно методом двоичного поиска выяснить, есть ли это слово в строке.
 **********************************************************************/
 
#include <stdio.h>  /* printf, putchar, puts, gets */
#include <string.h> /* strcmp */
#include <stdlib.h> /* calloc, free */
 
#define WORDS 10    // максимум слов в предложении
#define SYMBOLS 10  // максимум символов в слове
 
int  MyGetStr(char **);
void MySort(char **, int);
void MyBinarySearch(char **, int);
 
int main(void)
{
    int i, all_words;
    char **p;
    
// выделение памяти для вспомогательного массива указателей
    p = calloc(WORDS, sizeof(char *));
 
// выделение памяти под каждое слово в предложении 
    for(i = 0; i < WORDS; i++) {
        p[i] = calloc(SYMBOLS, sizeof(char));
    }
 
    printf("\n----- Введите слова (не более %d символов):\n", (WORDS * SYMBOLS) - 1);
// каждое слово в отдельный массив символов (создание словаря)
    all_words = MyGetStr(p);
 
    printf("\n----- Введены слова:\n");
    for(i = 0; i < all_words; i++) {
        putchar(' ');
        puts(p[i]);
    }
 
// сортировка массива указателей на слова
    MySort(p, all_words);
 
    printf("\n-----  Указатели на слова отсортированы:\n");    
    for(i = 0; i < all_words; i++) {
        putchar(' ');
        puts(p[i]);
    }
 
// запрос произвольного слова и поиск его в словаре
    MyBinarySearch(p, all_words);
 
// освобождение памяти
    for(i = 0; i < WORDS; i++)
        free(p[i]); 
    free(p);
 
    return 0;
}
 
 
/* Cчитывание потока символов и распределение по словам, 
 * пока не встретим символ конец строки '\n'  */
int MyGetStr(char **p) {
    const int OUT = 0;
    const int IN  = 1;
    int state = OUT;    
    int c, j = 0, i = 0;
 
    while((c = getchar()) != '\n') {
        if(c == ' ') {
            if(state == IN)
                p[i][j] = '\0';
            state = OUT; // устанавливаем состояние вне слова
        } else if(state == OUT) {
                    state = IN;
                    j = 0;
                    p[i][j] = c; // первый символ слова
                    i++;
                    j++;
        } else {
            p[i-1][j] = c; // последующие символы слова
            j++;
        }
    }
    p[i][j] = '\0'; // признак конца строки для каждого слова
    
    return i;
}
 
// сортировка массива указателей на слова
void MySort(char **p, int all_words)
{ 
    size_t i, j;
    
    for(i = 0; i < all_words - 1; i++) {
        for(j = 0; j < all_words - 1 - i; j++){
            if(strcmp(p[j], p[j+1]) > 0) {
                char *tmp = p[j];
                p[j] = p[j + 1];
                p[j + 1] = tmp; 
            }
        }
    }
}
 
 
// поиск слова в массиве методом двоичного поиска   
void MyBinarySearch(char **p, int all_words)
{   
    char find_word[SYMBOLS];
    size_t left, right, flag, index = 0;
 
    printf("\n Введите слово для поиска или '.' для завершения: ");
    gets(find_word);
    while(46 - find_word[0]) { // 46 - это код символа '.'
        left = flag = 0;
        right = all_words - 1;
        while(left <= right) {
            index = (left + right) >> 1;
            if(strcmp(find_word, p[index]) < 0)
                right = --index;        
            else if(strcmp(find_word, p[index]) > 0)
                left = ++index;         
            else{
                flag = 1;
                break;
            }
        }
        if(flag)
            printf("\n\tСлово есть в словаре\n");
        else
            printf("\n\tСлова в словаре нет\n");
        printf("\n Введите слово для поиска или '.' для завершения: ");
        gets(find_word);
    }
}
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 4
Комментарии
  1. Старый комментарий
    Аватар для HighPredator
    Возьмите за правило, если пишите на си,
    1) соблюдать сигнатуру главной функции
    2) не кастовать указатели на void в общем, и возвращаемые значения из аллокаторов в частности
    Запись от HighPredator размещена 17.11.2016 в 09:17 HighPredator вне форума
  2. Старый комментарий
    Аватар для Fon Eberkopff
    Цитата Сообщение от HighPredator
    Возьмите за правило, если пишите на си,
    1) соблюдать сигнатуру главной функции
    2) не кастовать указатели на void в общем, и возвращаемые значения из аллокаторов в частности
    1)
    Я так понимаю Вы имеете в виду параметры (int argc, char* argv[]). Но ведь в мою программу при её запуске ничего передовать не надо. И в то же время мне не нужно идентифицировать функцию main среди других одноимённых функций с различными параметрами (перегрузка в С++).
    Почему тогда мне нужно указывать параметры (int argc, char* argv[]) в случае моей программы?
    ---------
    2)
    Мне 2-ой совет не совсем понятен. Что значит "кастовать указатели на void"?
    Нашёл, что кастовать - "комп. жарг. осуществлять преобразование типов данных".
    Сalloc возвращает мне не типизированный указатель void *, а я его привожу к указателю на указатель на char (char **) в строке 27 и к указателю на char (char *) в строке 30.
    Мне не надо было этого делать? Почему?
    Запись от Fon Eberkopff размещена 17.11.2016 в 15:17 Fon Eberkopff вне форума
  3. Старый комментарий
    Аватар для HighPredator
    Я так понимаю Вы имеете в виду параметры (int argc, char* argv[])
    Не совсем.
    Но ведь в мою программу при её запуске ничего передовать не надо.
    Вот. Стандратом языка на текущий момент разрешены следующие формы главной функции:
    C
    1
    2
    
    int main(void);
    int main(int argc, char* argv[]);
    Первый кейс ваш. А вообще, когда вы не указываете void в скобках, то это означает, что функция может принимать любое их число. Пример: http://rextester.com/IDK92605

    Мне не надо было этого делать? Почему?
    Если коротко, то в си указатель на void всегда принудительно приводится к нужному типу (в отличие от С++ например, где этого нет). Поэтому, каст избыточен раз, и может привести к ошибкам два. Подробнее почитайте здесь: https://www.cyberforum.ru/c-be... 30688.html
    Запись от HighPredator размещена 18.11.2016 в 08:37 HighPredator вне форума
  4. Старый комментарий
    Аватар для Fon Eberkopff
    1) с сигнатурой разобрался (нашёл стандарт, увидел описание main + провёл пробы с Вашим примером с различным числом параметров).
    2) С кастом указателей пока полностью разобраться не могу, так как после ряда изменений (в т.ч. не связанных с приведением указателей) программа стала не адекватно завершаться. Я эту проблему описал в разделе Си для начинающих.
    А тот факт, что не надо кастовать указатели на void я вижу в целом ряде современных источников и сам стараюсь разобраться в этих вопросах глубже.

    Спасибо Вам за рекомендации по коду ))
    Запись от Fon Eberkopff размещена 22.11.2016 в 13:49 Fon Eberkopff вне форума
 
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru