4311

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

Контрольная

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

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

Русский

2012-11-16

63 KB

11 чел.

Строки

В языке С отсутствует строковый тип, работа со строками организована путем использования одномерных массив типа 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(), которая принимает в качестве аргументов символ и указатель строки. Функция должна возвращать ненулевое значение ("истинно"), если символ присутствует в строке, и нуль ("ложно"), в противном случае.


 

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

886. Совершенствование государственной поддержки малого и среднего бизнеса в России 678 KB
  Теоретические основы развития малого и среднего бизнеса в Российской Федерации. Роль малого и среднего бизнеса в развитии территории региона. Налоговая политика государства в отношении малого и среднего бизнеса: история и современное состояние. Развитие малого и среднего бизнеса в Ростовской области.
887. Разработка и реализация управленческих стратегий 174.5 KB
  Особенности и правила разработки управленческой стратегии. Анализ внутренней и внешней среды предприятия в диагностике проблем в процессе разработки и реализации управленческой стратегии (на примере предприятия). Предложения по разработке и реализации управленческой стратегии в предприятии.
888. Охорона праці в галузі 466.5 KB
  Зміст домашніх завдань та методичні рекомендації з виконання домашнього завдання. Вплив людини як біологічного об'єкту. Інформація про стан машини, що обробляється людиною. Значення світлової характеристики світлових прорізів при бічному освітленні.
889. Теорія алгоритмів 173.5 KB
  Введення до теорії алгоритмів. Сучасний погляд на алгоритмізацію. Основні алгоритмічні конструкції. Модульна структура програмних продуктів.
890. Расчёт рекуператора 147 KB
  Определение расхода продуктов сгорания через рекуператор. Определение среднеарифметических температур воздуха и продуктов сгорания. Определение коэффициента теплоотдачи от продуктов сгорания к стенке. Определение действительной скорости воздуха и продуктов сгорания.
891. Разработка воздушного радиатора транзистора КТ846А 1.53 MB
  Транзистор кремниевый мезапланарный структуры n-p-n импульсный. Коэффициент теплопроводности материала радиатора. Соотношение для расчета средней температуры радиатора. Зависимость коэффициента объемного расширения от температуры.
892. Способы обучения одаренных детей 158 KB
  Теоретические основы проблемы воспитания и обучения одаренных детей. Сложности психического развития одаренных детей. Обучение одаренных детей. Подготовка педагога к взаимодействию с одаренными детьми. Неформализованные методы изучения одаренных детей.
893. Экономическое обоснование оптимальной схемы доставки машин и оборудования из Петрозаводска в Ростов-на-Дону 744 KB
  Анализ задания и обоснование расчетных вариантов схемы доставки груза. Анализ возможных маршрутов доставки в прямых и смешанных транспортных сообщениях и выбор расчетных вариантов схемы доставки груза. Определение себестоимости эксплуатационного содержания судов. Определение путевой составляющей издержек перевозки грузов водным транспортом.
894. Строительство железных дорог, путь и путевое хозяйство 170 KB
  Требования безопасности при разборке и сборке звеньев путевой решетки. Особенности технологии ремонта бесстыкового пути и ремонта звеньевого пути с укладкой плетей бесстыкового пути. Производственный состав ПМС.