4311

Строки в языке Си

Контрольная

Информатика, кибернетика и программирование

Строки В языке С отсутствует строковый тип, работа со строками организована путем использования одномерных массив типа char. Строка в С – это массив символов, заканчивающийся нулевым байтом. Каждый символ строки размещается в отдельном ба...

Русский

2012-11-16

63 KB

9 чел.

Строки

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

Строка в С – это массив символов, заканчивающийся нулевым байтом. Каждый символ  строки размещается в отдельном байте.

Нулевой байт – это байт, каждый бит которого равен нулю. Для нулевого байта определена специальная символьная константа ‘\0’. Это следует учитывать при описании соответствующего массива символов. Если строка должна содержать n символов, то в описании массива следует указать n+1 элемент.

Например при описании массива

char name  [20];

следует учитывать, что строка сможет содержать не более 19 символов, а последний байт зарезервирован под нулевой байт. Если при вводе в массив name  было введено меньше 19 символов, элементы массива, следующие за нулевым байтом, будут содержать случайные значения. Пусть например, в массив name было введено имя Александр, тогда в девяти байтах будут размещены символы, составляющие имя, десятый байт – это нулевой байт, и 10 байт окажутся заполнены случайными значениями. На рис 1. показано размещение массива name  в памяти.

А

л

е

к

с

а

н

д

р

‘\0’

                Рис. 1. Размещение массива name в памяти.

Инициализация строк

Инициализация строк может выполняться так, же как и инициализация одномерного массива – с помощью списка констант например:

char  str[ ]  =  {‘П’ , 'р', 'и','в','е','т',’\0’};

Однако для строк существует более удобный способ инициализации – с помощью строковой константы, например:

char  str[ ]  = “Привет”;

При использовании любого из этих способов инициализации компилятор подсчитывает количество символов и в соответствии с этим определяет размер массива.

Ввод – вывод строк

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

Для ввода строк существует специальная функция  gets(), которая читает строку, пока не будет нажата клавиша Enter.  Функция gets() позволяет ввести строки, содержащие пробелы.

Строку можно ввести и с помощью функции scanf(), используя спецификацию формата %s. Функции scanf() вводит символы до первого пробела. Обе функции автоматически ставят в конце строки нулевой байт.

Для вывода строк можно использовать функции     printf() и   puts()

В примере 1 показана программа, выполняющая ввод-вывод строк. Обе функции выводят содержание массива до первого нулевого байта.

Пример  1.  Ввод  - вывод строк.

#include <stdio.h>
            #include <conio.h>
              void main(void)

 {

//объявление строки как массива
 
char str[80];                                                    //зарезервировали место в памяти под строку

   clrscr();

  printf("Введите строку длиной менее 80 символов: ");

  gets(str);                                                //читает строку с клавиатуры, пока не нажата Enter

//вывод строки с помощью функции printf по спецификации %s

   printf("Вы ввели строку %s\n",str);

   printf("Введите еще одну строку длиной менее 80 символов: ");

   scanf("%s",str); //читает строку с клавиатуры, пока не  встретится пробел

   printf("Вы ввели строку %s\n",str);

//вывод строки с помощью функции puts

   puts(str);

   getch();

   }

Объединение двух строк

 Процесс объединения двух строк состоит в том, что символы, содержащиеся в одной строке, добавляются в конец другой. Этот процесс называется конкатенацией (concatenation). Для выполнения объединения двух строк следует организовать цикл, в котором анализируются символы  первой строки, пока не будет найден нулевой байт и сдвигается текущий индекс элемента массива на конец строки. Затем, во втором цикле, который исполняется, пока не найден нулевой байт второй строки, символы из второй строки копируются в конец первой.  В примере 2 показана программа, выполняющая конкатенацию строк.

Пример 2.  Объединение двух строк: к концу одной строки дописывается вторая и результат выводится

                
#include <conio.h>
                #include <stdio.h>

      void main(void)
                  {
                        char s[80], t[80];
                                 //резервирование места в памяти под строки

            int i=0,j=0;

            clrscr();

             puts("Введите первую строку ");

             gets(s);

             puts("первая строка");

             puts(s);

             puts("Bведите вторую строку ");

             gets(t);

             puts("вторая строка");

             puts(t);

//цикл выполняется, пока не будет найден  нулевой байт - конец первой строки

       while(s[i] != '\0')

       {

//сдвигаем текущий индекс элемента первой строки на ее конец   

        i++;

        }

//в этом цикле к концу первой строки дописывается вторая  цикл выполняется, пока не найден //конец второй строки

  while(t[j] != '\0')

   {

       s[i]=t[j];  //дописываем к первой строке символы второй

        i++;

        j++;

     }

 s[i]= '\0';                                           //дописываем нулевой байт к результирующей строке

  puts("результат:");

   puts(s);

  }

Сравнение двух строк

В С нельзя непосредственно сравнивать значения двух строк с помощью, например, такого условия:

      if (str1 = = str2)

Для сравнения двух строк можно воспользоваться библиотечной функцией strcmp(). Эта функция возвращает нулевое значение, если строки совпадают и ненулевое значение при несовпадении строк.

В примере 3 показана программа, в которой используется функции strcmp() для сравнения двух строк. Эта программа не всегда может давать правильный результат, особенно при сравнении строк, содержащих русские буквы. В примере 4 показано, как можно написать собственную программу для выполнения посимвольного  сравнения двух строк.

Пример 3. Сравнение двух строк с помощью библиотечной функции strcmp().

#include <stdio.h>     
           #include <string.h>
         //для функции strcmp()

void main(void)

{

       int flag=0;

       char name[10],  name1[10];

       clrscr();

       puts( "Введите первую строку" );

       gets( name );

       puts( "Введите вторую строку" );

       gets( name1 );

      if( strcmp( name, name1 ) == 0 )

       flag=0;

       else flag=1;

     if(flag==1)

     puts("Строки не совпадают");

      else

      puts("Строки  совпадают");

      }

Пример 4. Сравнение двух строк с помощью собственной программы.

     #include <stdio.h>

      void main(void)

      {

int  index,  flag=0;

char name[10], name1[10];

puts("Введите первую строку");

gets(name);

puts("Введите вторую строку");

gets(name1);

 for(index=0;  name[index]!= '\0';  index++)

  if(name[index] != name1[index])

   {

       flag=1;

       break;

     }

   if(flag==1)

   puts("Строки не совпадают");

   else

    puts("Строки  совпадают");

    getch();

   }


Примеры программ

Пример 1. Программа, распечатывающая  введенную строку символов, удалив из нее символы  * и удвоив  символы A. Программа выполняет анализ вводимых символов и записывает их в строку str.  Если введенный символ * - то он не заносится в строку str, а если введенный символ – A или а, то в строку str он записывается дважды. Затем полученная строка выводится.

// Можно обойтись без массива, если в цикле WHILE

// сразу осуществлять вывод нужных символов

//    while((getchar())!='\n')

// { if(ch=='*')

//    continue;    // если * -начать цикл заново,т.е. прочесть нов сим

//   if(ch=='A' || ch=='a')putchar(ch);

//    putchar(ch);

//  }

#include <stdio.h>

 void main(void)

 {

   int i,k=0;

   char str[80],ch;

   puts("\nВведите строку символов");

   while((ch=getchar())!='\n')

 {

if(ch=='*')

   continue;    // если * -начать цикл заново, т.е. прочесть нов символ

  if(ch=='A' || ch=='a')

   str[k++]=ch;

   str[k++]=ch;

   }

   for(i=0; i<k; i++)

   putchar(str[i]);

   }

Пример 2. Переворот символьной строки S (символы  строки располагаются в обратном порядке). Перевернутая строка располагается в той же области памяти, т.е. дополнительный массив не заводится.
                  
#include <stdio.h>
                  #include <conio.h>

     #define MAXLINE 1000 //макс. размер входной строки

  void main(void)

  {

       char s[MAXLINE]; //текущая строка ввода

       int i,j;

       char temp;  //для хранения одного символа строки

       i=0;

       clrscr();

     puts("Введите строку");

     gets(s);

     while(s[i] !='\0')             //ищем конец строки

       ++i;                     //увеличиваем на единицу количество найденных в строке символов

     --i;                //смещаемся назад от '\0' - признака конца строки

      j=0;             //начало перевернутой строки

      if(s[i]=='\n')  //если в строке присутствует символ новой строки

          --i;                        //смещаемся назад от признака новой строки

      while(j<i)       //j - индекс первого символа строки, i-последнего

      {  

// в процессе обмена символов j увеличивается (продвигается

   // к концу строки, а i уменьшается (движется к началу)

   temp=s[j]; // запоминаем символ в начале строки в дополнителной переменной

             s[j]=s[i];     //обмениваем символы

              s[i]=temp;

     --i;           //движемся к началу строки

               ++j;          //движемся к концу строки

 }

 // выводим перевернутую строку

 puts("  Перевернутая строка");

 puts(s);

 getch();

 }

Пример 3.  Программа, выполняющая копирование строки s1 в строку s2

# include <stdio.h>

 void main(void)
 {
      char s1[80],s2[80];
      int i;

      puts("введите исходную строку");

// цикл, в котором строка вводится посимвольно в массив

// выполнение цикла заканчивается, если была нажата клавиша Enter

      for(i=0;i<80;i++)

      {

            scanf("%c",s1+i);

            if(s1[i] =='\n')

            break;

       }

     s1[i]='\0';

     puts("Исходная строка");

     puts(s1);

     i=0;

//копируем строку s2  в строку s1

      while((s1[i])!='\0')

     {

          s2[i]=s1[i];

          i++;

      }

   s2[i]='\0';
   puts("
Скопированная строка" );
    puts(s2);
    }

Пример 3. Обьединение двух строк к концу строки s дописывается строка t, вычисляется длина полученной строки.  Память под строки распределяется динамически.

#include <alloc.h>

#include <stdio.h>

void main(void)

{

   char *t, *s;                         //объявление указателей на данные типа char

   int i=0;

//динамическое распределение памяти под строки

   s=(char *)malloc(160);

   t=(char *)malloc(80);

   puts("Введите первую строку ");

   gets(s);

   puts("первая строка");

   puts(s);

   puts("Bведите вторую строку ");

   gets(t);

   puts("вторая строка");

   puts(t);

while(*s != '\0')         //выполнять, пока не найден конец первой строки

   {

       i++;

       s++;                         //сдвигаем указатель в конец первой строки

    }

while(*t != '\0')          //выполнять, пока не найден конец второй строки

    {

        *s++ = *t++;         //дописываем символы второй строки к первой
        
             i++;

     }

  *s='\0';                              //дописываем нулевой байт к концу результирующей строки

    printf("длина результирующей строки i=%d\n", i);

while(--i >= 0)                           //сдвигаем указатель в начало результирующей строки

    {

         s--;

     }

    puts("результат:");

    puts(s);

}

Пример 3.  Программа, в которой используются указатели на строки.

#include <stdio.h>

void main(void)

{

char s[]="строка как массив";

char *ps=s                                  //указатель ps инициализирован значением адреса строки s

char *ps1,*ps2,*ps3;                //объявление указателей на строки

ps1="В языке  си в одну\n"  //присвоение указателю ps1 адреса строковой константы

        "строку можно записать\n"

       "целое стихотворение\n";

ps2="предложение не будет\   //присвоение указателю ps2 адреса строковой константы

         перенесено на следующую строку";

ps3="одна"         //присвоение указателю ps3 адреса строковой константы

       " строка";

//цикл вычисления длины строки s, адрес которой хранит указатель ps. Выполнять, пока не найден конец строки

while(*ps != '\0')

     ps++;

 printf("длина строки= %d\n",ps-s);

 puts(ps1);

 puts(ps2);

 puts(ps3);

}

ЗАДАЧИ ДЛЯ РЕШЕНИЯ

1

Напишите программу, выполняющую копирование одной строки в другую. Для работы со строками используйте указатели.

2

Составить программу, определяющую позицию самого правого   вхождения  заданного символа в исходную строку

3.

Создайте функцию is_within(), которая принимает в качестве аргументов символ и указатель строки. Функция должна возвращать ненулевое значение ("истинно"), если символ присутствует в строке, и нуль ("ложно"), в противном случае.


 

А также другие работы, которые могут Вас заинтересовать

82337. Хан Абылай и его место в истории казахского народа 28.98 KB
  Его дед тоже Абылай был владетелем города Туркестана прославился воинскими доблестями и получил грозное прозвище Канишер кровопийца. В 13 лет Абылай лишился отца убитого во время междоусобиц рано поступил на службу. Абылай понимал что главный враг Казахстана – джунгары поэтому стремится держать пророссийскую ориентацию.
82338. Казахстан в середине 60-х нач. 80-х годов. Социально-политическое развитие 30.01 KB
  Состав депутатов Верховного Совета СССР где были представлены чабаны колхозники рабочие промышленных предприятий техническая интеллигенция люди науки и искусства партийные и хозяйственные руководители и служил якобы подтверждением этой новой общественнополитической ситуации в обществе. Группа деятелей высшего политического руководства СССР в глубокой тайне подготовила смещение Н. Суслов и председатель КГБ СССР В. Смена политического руководства СССР в октябре 1964 года вскоре стала сказываться и на состоянии культуры.
82339. Восстание Кенесары Касымова (причины, характер, движущие силы, итоги) 27.95 KB
  Движущие силы численность: все слои населения – крестьянешаруа бии батыры султаны 20 тысяч человек все слои населения – крестьянешаруа бии батыры султаны Ход восстания: осень 1837 – организация отрядов повстанцев; начало открытого сопротивления царскому правительству; весналето 1838 – вооруженные столкновения с царскими отрядами нападение на аулы ненавистных султанов; разгром Акмолинской крепости отрядом Кенесары; увеличение отрядов перемещение центра восстания из Среднего в Младший жуз; 1840 – вторжение Кенесары в Кокандское...
82340. Экономическое развитие Казахстана в 60-ые годы ХХ. Рост новых городов 32.27 KB
  Такой подход положительно сказался на тонусе общественной жизни Казахстана. Удельный вес Казахстана в общесоюзной добыче железной руды достиг 54 . На территории Казахстана были размещены космодром и атомный полигон.
82341. Понимание невербальной эмоциональной экспрессии младшими подростками 389.5 KB
  Работая в этих областях отечественные психологи-практики столкнулись с фундаментальной ошибкой сформировавшейся в результате полного игнорирования тех идей психологии невербального общения которые имели отношения к вечной проблеме взаимосвязи души и тела экспрессии и психологических особенностей человека.
82342. Разработка программы построения таблицы истинности логической функции 155 KB
  Истинность логических выражений помогает определить таблица истинности логических функций. С помощью таблиц истинности можно устанавливать эквивалентность выражений и справедливость равенств законов алгебры логики.
82343. ТЕОРЕТИЧНІ ОСНОВИ ФОРМУВАННЯ ФІНАНСОВОЇ СТРАТЕГІЇ РОЗВИТКУ ПІДПРИЄМСТВА 4.07 MB
  З метою подальшого розгляду процесу формування фінансової стратегії підприємства доцільно уточнити поняття фінансового розвитку підприємства стратегії та фінансової стратегії підприємства. В загальному під розвитком розуміють надбання нової якості яка зміцнює життєздатність підприємства в умовах змін середовища.
82344. Проект реконструкции участка диагностики автосервиса с целью увеличения количества обслуживаемых клиентов 1.31 MB
  Цель дипломного проекта заключается в реконструкции участка диагностики связанной с совершенствованием технологического процесса внедрением нового оборудования улучшением условий труда с целью увеличения количества обслуживаемых клиентов...
82345. Технология приготовления скомплектованного обеда из трех блюд 2.6 MB
  Неотъемлемой частью культуры каждого народа является кухня. Недаром этнографы начинают исследование жизни любого народа с изучения его кухни, ибо в ней в концентрированном виде отражается история, быт и нравы народа. Русская кухня в этом смысле не исключение, она так же является частью нашей культуры, нашей истории.