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

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

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

В этом случае, несмотря на то, что в Си нет динамических массивов и их размер должен указываться при инициализации, при передаче параметров допускается указывать "открытые" массивы. Но тогда разработчик должен самостоятельно позаботиться о том, чтобы сообщить функции размер конкретного массива, который передается в ходе работы программы. В приведенном примере передаваемая строка всегда заканчивается символом конца строки '\0', поэтому можно последовательно перебирать элементы массива, пока не встретится символ '\0', и не опасаться выйти за границы массива. Если же конечного символа не предусматривается (в большинстве случаев в массиве хранятся не строки, а единообразные данные, не заканчивающиеся никаким специальным элементом), то размер массива следует передать дополнительно:

void encodeAtbash(char str[], int arrayLength)
  {
    int i;
    for (i = 0; i < arrayLength; i++)
    {
      . . .
    }
  . . .
}  
    

А теперь вернемся к задаче, рассмотренной ранее в разделе 2, и посмотрим, как будет выглядеть реализация программы, соответствующая сформулированным требованиям.

Чтение строки может быть выполнено аналогично приведенному примеру кодирования строки алгоритмом "Атбаш", но считывать необходимо не 11, а 81 символ. Последний 81-й символ нужен, чтобы обработать ситуацию, когда пользователь ввел более 80-ти символов.

/*******************************************************
Date: 10 January 2013
Description: string reading and encoding sample 2
*****************************************************/
#include <stdio.h>
/*******************************************************
* Name : isEnglishLetter
*
* Purpose : сhecks whether the symbol belongs to
* English alphabet
* Input : c - symbol
* Output : none
* Return : 1 – belongs, 0 – do not belongs
*
*****************************************************/
int isEnglishLetter(char c)
{
  if( (c >= 'a') && ( c <= 'z' ) )
  {
    return 1;
  }
  if ( (c >= 'A') && (c <= 'Z') )
  {
    return 1;  
  }
  return 0;
}
/*******************************************************
* Name : isRussianLetter
*
* Purpose : checks whether the symbol belongs to
* Russian alphabet
* Input : c - symbol
* Output : none
* Return : 1 – belongs, 0 – do not belongs
******************************************************/
int isRussianLetter(char c)
{
  if( (c >= 'а') && ( c <= 'я' ) )
  {
    return 1;
  }
  if ( (c >= 'А') && (c <= 'Я') )
  {
    return 1;
  }
  return 0;
}
/*******************************************************
* Name : isNumber
*
* Purpose : checks whether the symbol is number
* Input : c - symbol
* Output : none
* Return : 1 – number, 0 – not a number
******************************************************/
int isNumber(char c)
{
  if( ((int)c >= (int)'0') && ( (int)c <= (int)'9' ) )
  {
    return 1;
  }
  return 0;
}
/*******************************************************
* Name : isDelimeter
*
* Purpose : checks whether the symbol is a delimiter
* Input : c - symbol
* Output : none
* Return : 1 – delimiter, 0 – not a delimiter
******************************************************/
int isDelimeter(char c)
{
  if( (c == ',') || (c == '.') || (c == ' ') || (c == '\0') )
  {
    return 1;
  }   else
    {
      return 0;
    }
}
/*******************************************************
* Name : testString
*
* Purpose : test string for correctness
* (according requirements)
* Input : str (string to check)
* Output : none
* Return :
* -1 bad string
* 0 good string (only acceptable characters)
******************************************************/
int testString(char *str)
{
  int start;
  int goodSymb;
  int count;
  count = 0;
  start = 0;
  while(*str)
  {
    goodSymb = 0;
    if (isEnglishLetter(*str))
    {
      start = 1;
      goodSymb = 1;
    }
    if (isRussianLetter(*str))
    {
      start = 1;
      goodSymb = 1;
    }
    if (isNumber(*str))
    {
      start = 1;
      goodSymb = 1;
    }
    if ( (*str) == ' ' )
    {
      goodSymb = 1;
    }
    if ( (isDelimeter(*str)) && start )
    {
      goodSymb = 1;
    }
    if (goodSymb == 0)
    {
      return 0;
    }   else
    {
      str++;
      count++;
    }
  }
  if (count > 10)
  {
    return 0;
  } else
  {
    return 1;
  }
}
/*******************************************************
* Name : replaceLineEnd
* Purpose : replaces ending '\n' (if exists)
* symbol by '\0' symbol
* except English small characters
* Input : str (string)
* Output : str (string)
* Return : none
******************************************************/
void replaceLineEnd(char *str)
{
  int i;
  char temp[2];
  for(i=0; ( (*(str+i)!='\n') && (*(str+i)!='\0') ); i++);
  if ( *(str+i) == '\0' )
  {
    /* empty input buffer */
    while (temp[0] != '\n') \
    {
    fgets(temp,2,stdin);
    }
  }
  if ( *(str+i) == '\n' )
  {
    *(str+i) = '\0';
  }
}
/*******************************************************
* Name : readString
*
* Purpose : reads string from keyboard
* Input : str (empty string)
* Output : str (inputted string)
* Return : none
******************************************************/
void readString(char *str)
{
  /* reads only 81 chars from keyboard, 82 sets to '\0' */
  fgets(str,82,stdin);
  replaceLineEnd(str);
}
/*******************************************************
* Name : change231
* Purpose : ncodes word in string str using 231 exchange
* Input : str (string),
* startPos – position in string
* where the word starts from
* Output : str (encoded string)
* Return : encoded word end position in str
******************************************************/
int change231(char *str, int startPos)
{
  int i;
  char temp;
  i = startPos + 1;
  while (!isDelimeter(str[i]))
  {
    temp = str[i];
    str[i] = str[i-1];
    str[i-1] = temp;
    i++;
    if (((i-startPos)%3 == 0) && (!isDelimeter(str[i])))
    {
      i++;
    }
  }  
  return i;
}
/******************************************************
* Name : processString
* Purpose : encode words in string
* leaving delimiters unchanged
* Input : str (string),
* Output : str (encoded string)
* Return : none
******************************************************/
void processString(char *str)
{
  int i;
  i = 0;
  while( *(str+i) != '\0' )
  {
    if (isDelimeter(*(str+i)))
    {
      i++;
    } else
    {
      i = change231(str, i);
    }
  }
}
int main()
{
  /* max length 80 + 1 for ending symbol
    + 1 to test >80 entered symbols */
  char str[82];
  printf("Введите строку для кодирования\n");
  readString(str);
  while(*str != '\0')
  {
    if (testString(str) == 0)
    {
      printf("Ошибка во входной строке\n");
    } else
    {
      processString(str);
      printf("%s\n", str);
    }
      printf("Введите строку для кодирования\n");
      readString(str);
  }
  printf("Работа закончена");
  return 0;
}
    
< Лекция 4 || Лекция 5: 12345 || Лекция 6 >
Ильдус Кучкаров
Ильдус Кучкаров
Россия, Санкт-Петербург, СПбГУ
Антон Конычев
Антон Конычев
Россия, Москва, МГУПИ, 2013