Опубликован: 05.11.2013 | Доступ: свободный | Студентов: 414 / 22 | Длительность: 11:51:00
Лекция 5:

Препроцессор, оформление программы и средства ввода/вывода

< Лекция 4 || Лекция 5: 12345 || Лекция 6 >

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

if ( (*str) == ' ' )
{
  goodSymb = 1;
}  
    

а когда start равна единице, допускается любой разделитель (точка, запятая, пробел):

if ( (isDelimeter(*str)) && start )
{
  goodSymb = 1;
}  
    

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

Сама перестановка символов выполнена последовательно попарно. Требуемый результат - 231 получается, если сначала переставить первый символ со вторым (получив 213) и далее второй с третьим (получив как раз 231). Такой подход оказывается справедлив и в случае, когда остается два символа (12 - 21), т.е. алгоритм перестановки сводится к работе лишь с двумя рядом стоящими символами (перемене их мест). Однако требуется перестановка только в рамках тройки символов, поэтому на каждом третьем шаге следует пропустить одну позицию:

if (((i-startPos)%3 == 0) && (!isDelimeter(str[i])))
i++;  
    

Алгоритм основной программы уже был определен ранее.

  1. Ввести входную строку.
  2. Если строка пустая, то закончить работу.
  3. Преобразовать входную строку.
  4. Вывести преобразованную строку.
  5. Ввести очередную входную строку и вернуться к действию (2).

Соответственно будет выглядеть и реализация.

  1. Ввести входную строку:
    printf("Введите строку для кодирования\n");
    readString(str);  
            
  2. Если строка пустая, то закончить работу:
    while(*str != '\0')
    {
    . . .
    }
    printf("Работа закончена");
    return 0;  
            
  3. Преобразовать входную строку:
    if (testString(str) == 0)
    {
      printf("Ошибка во входной строке\n");
    } else
    {
      processString(str);
      printf("%s\n", str);
    }  
            
  4. Вывести преобразованную строку:
    processString(str);
    printf("%s\n", str);  
            
  5. Ввести очередную входную строку и вернуться к действию (2):
    while(*str != '\0')
    {
      ...
      printf("Введите строку для кодирования\n");
      readString(str);
    }  
            

Вопросы и задачи для самостоятельного решения

  • Как можно задать числовую константу в Си?
  • Сколько необходимо создать файлов, чтобы реализовать модуль в Си?
  • Зачем нужны заголовочные файлы в Си?
  • В каких случаях возможно переполнение буфера при вводе строки? Какими способами можно этого избежать?
  • Напишите программу перевода десятичного числа в шестнадцатеричное. Входное число должно считываться из стандартного потока ввода (клавиатура). Перевод должен работать для чисел длиной не менее 100 цифр.
  • Напишите программу кодирования слова методом перестановки символов 3-1-2. Входное слово должно считываться из стандартного потока ввода (клавиатура). Кодирование должно работать для слов длиной не менее 300.
< Лекция 4 || Лекция 5: 12345 || Лекция 6 >
Ильдус Кучкаров
Ильдус Кучкаров
Россия, Санкт-Петербург, СПбГУ
Антон Конычев
Антон Конычев
Россия, Москва, МГУПИ, 2013