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


 

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

37904. КАЧЕСТВЕННЫЙ И ПОЛУКОЛИЧЕСТВЕННЫЙ СПЕКТРАЛЬНЫЙ АНАЛИЗ СПЛАВОВ 4.23 MB
  Определить процентное содержание химического элемента в сплаве. Спектр каждого элемента является строго его индивидуальной характеристикой и поэтому может быть использован для анализа вещества. Атом состоит из положительно заряженного ядра в котором сосредоточена практически вся его масса и отрицательно заряженных электронов число которых в нейтральном атоме совпадает с порядковым номером элемента в периодической системе Менделеева. На энергетических схемах возможные значения энергии атома изображаются горизонтальными линиями причем все...
37905. Исследования полупроводникового диода 566 KB
  С точки зрения зонной теории полупроводниками являются кристаллические вещества у которых при 0 К валентная зона полностью заполнена электронами а ширина запрещенной зоны невелика например для германия она равна 072 эВ. Выясним природу этих носителей на примере полупроводника из германия. Все атомы германия нейтральны и связаны друг с другом ковалентными связями. Чтобы создать проводимость необходимо разорвать хотя бы одну из связей удалив из атома германия электрон и перенеся его в какуюлибо другую кристаллическую ячейку где все...
37906. Изучение статических характеристик и определение коэффициента усиления транзистора 84.5 KB
  Инжекция носителей тока. Инжекция носителей тока В основе работы транзистора лежит явление полупроводников р и n – типа р–n – переход к которому приложено внешнее электрическое поле в пропускном прямом направлении рис.1 В этом случае потенциальный барьер основных носителей на границе р–n – перехода снижается и под влиянием внешнего поля дырки переходят из р в n – полупроводник а электроны в обратном направлении из n в р – полупроводник и в цепи возникает прямой ток. Процесс рекомбинации происходит не...
37907. ИССЛЕДОВАНИЕ ТЕМПЕРАТУРНОЙ ЗАВИСИМОСТИ МЕТАЛЛОВ И ПОЛУПРОВОДНИКОВ 4.96 MB
  Электропроводность зависит от температуры структуры вещества и от внешних воздействий напряженности электрического поля магнитного поля облучения и т. Характер зависимости σ от температуры Т различен у разных веществ. Увеличение температуры приводит к возрастанию тепловых колебаний кристаллической решетки на которых рассеиваются электроны и σ уменьшается. при более низких температурах когда влиянием тепловых колебаний на рассеяние электронов можно пренебречь сопротивление практически не зависит от температуры.
37908. Определение постоянной Планка методом задерживающего потенциала 120 KB
  Михайлов Определение постоянной Планка методом задерживающего потенциала: Методические указания к лабораторной работе № 80 по курсу общей физики Уфимск. Методические указания знакомят студентов с уравнением Эйнштейна для фотоэффекта и с методом задерживающего потенциала позволяющего определять постоянную Планка. Студентам предлагается экспериментально получить график зависимости задерживающего потенциала от частоты падающего на фотокатод света и вычислить постоянную Планка и работу выхода.
37909. ДИФРАКЦИЯ ЭЛЕКТРОНОВ 951 KB
  Гипотеза деБройля 4 2. Контрольные вопросы 11 Список литературы 11 ЭЛАБОРАТОРНАЯ РАБОТА № 85 ДИФРАКЦИЯ ЭЛЕКТРОНОВ Цель работы Изучение гипотезы деБройля о волновых свойствах микрочастиц. Определение длины волны деБройля электронов дифрагированных на образцах с кубической кристаллической решеткой. Теоретическая часть Гипотеза деБройля В 1924 г.
37910. Исследование зависимости теплового излучения абсолютно черного тела от температуры 104 KB
  Лабораторная работа № 86 Исследование зависимости теплового излучения абсолютно черного тела от температуры 1. Цель работы Исследование зависимости интегральной излучательной способности абсолютно черного тела от температуры и проверка выполнения закона СтефанаБольцмана. зависит от температуры тела. Для спектральной характеристики теплового излучения вводится понятие излучательной способности тела или спектральной плотности излучательности 2.
37911. Изучение поляризованного света и внутренних напряжений в твердых телах оптическим методом 338.5 KB
  16 Лабораторная работа № 66 Изучение поляризованного света и внутренних напряжений в твердых телах оптическим методом 1. Закон Малюса Из электромагнитной теории света вытекает что световые волны поперечны. Естественные источники света излучают волны неполяризованные. При взаимодействии света с веществом основное действие оказывает электрическая составляющая электромагнитного поля световой волны электрические взаимодействия сильнее магнитных.
37912. ИЗУЧЕНИЕ ДИСПЕРСИИ СВЕТА 641.5 KB
  2 угол при вершине которой т. преломляющий угол равен P падает световая волна частоты ω угол падения равен i1. Угол наименьшего отклонения δ преломляющий угол P и показатель преломления связаны между собой соотношением .2 Угол отклонения лучей призмой тем больше чем больше преломляющий угол призмы.