Архив метки: функция

Си — работа со строками

Си работа со строками

Объявление строк

Строка в языке Си представляет собой одномерный массив символов, последним элементом которой является символ конца строки – нуль (строка, завершающаяся нулем, то есть NULL terminated string).

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

Первый способ:

Объявления массива символов (не забудьте добавить место для завершающего нуля):

char s[40+1];

Второй способ:

Присвоить строковой переменной начальное значение (при этом длину строки компилятор может вычислить сам):

char s[] = "Пример инициализации строки";

Справа от знака присваивания записана строковая константа. В конце строки автоматически добавляется ноль (‘\0’). Константы символьных строк помещаются в класс статической памяти.

Третий способ:

Неявное указание, что используется массив. В левой части от знака присваивания указывается указатель на символ:

char *s="Второй вариант инициализации";

Переменная s будет указателем на то место в оперативной памяти, где располагается строковая константа. В такой форме записи кроется потенциальная ошибка, заключающаяся в том, что указатель на  символ часто называют строкой. Представленная ниже запись – это только указатель на символ, так как для размещения строки место не предусмотрено:

char *s;

Ввод строки со стандартного устройства ввода (клавиатуры)

Для работы со строками есть набор функций. Для ввода со стандартного устройства ввода (клавиатуры) чаще всего используются библиотечные функциями из модуля стандартного ввода-вывода: scanf и gets.

Для ввода строки с помощью функции scanf, использует формат «%s», причем обратите внимание на то, что перед идентификатором строки не используется знак адреса «&», так как одномерный массив уже представлен указателем на его начало:

scanf("%s", s);

Функция gets() считывает символы до тех пор, пока не достигнет символа перехода на новую строку. Функция принимает все символы вплоть до символа перевода строки, но не включает его. К концу строки добавляется завершающий ноль (‘\0’). Функция gets() помещает считанную с клавиатуры последовательность символов в параметр типа строка и возвращает указатель на эту строку (если операция завершилась успешно), или NULL (в случае ошибки). В приведенном ниже примере при успешном завершении операции, на экран будет выведено две одинаковые строки:

#include <stdio.h>
int main()
{  char s[50];
char *p;
p=gets(s);
printf(" \n Введена строка %s. ",s);
if (p) printf(" \n Введена строка %s. ",p);
return 0;
}

Попутно заметим, что функция gets часто используется для ввода лю-бых данных с клавиатуры в виде строки с целью дальнейшего преобразования функцией sscanf к нужному формату или для предварительного анализа вводимых данных, например:

#include <string.h>
#include <stdio.h>
#include <conio.h>
int main()
{ char s[50];   int x, err;
do
   {   printf(" \n Введите целое число -> ");
       gets(s);
       err=sscanf(s, "%d",&x);
       if (err!=1) printf(" \n Ошибка ввода. ");
  } while (err!=1);
  printf("\n Введено целое число -> %d", x);
return 0;
}

Вывод строк на стандартное устройство вывода (экран монитора)

Для вывода строк на стандартное устройство вывода (экран монитора) можно использовать две функции printf и puts. В функции printf в качестве формата передается «%s». Удобство использования этой функции заключается в том, что помимо строки можно сразу выводит данные других типов. Особенность функции puts заключается в том, что после вывода строки автоматически происходит переход на следующую строку.

Функции для работы со строками

Для преобразования строк в языке Си предусмотрена библиотека string. Каждая из функций имеет свой формат записи (прототип).

Наиболее  используемые функции рассмотрены в этой статье. — читать

Пример программ(листинг) работающей со строками

Пример №1(листинг) | Пример№2 (Листинг)

Строки в С++ Листинг программы

Тема: Строки

Задание: :  В 2-х предложениях найти и распечатать совпадающие слова.

Листинг

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <windows.h>

#define N 20

  //  ПРЕДВАРИТЕЛЬНОЕ ОБЪЯВЛЕНИЕ ФУНКЦИЙ
  // Заголовок программы
      void Title();
  // Ввод предложения
      void InpPredl (char predl[]);
  // Ввод предложения
    void InpPredl(char predl[]);
      // Ввод предложения
    void InpPredl2(char predl[]);
  // Выделение из предложения
     void Select(const char *predl, char m[][N],char *sel, int *n);
  // Поиск повторов слов
     void FindDuplicate(char slova[][N], char slova2[][N], int sl, int rz);
  // Вывод результата
     void OutPredl(char *s1, char *s2);

inline void rus()  // Русификация вывода в консольное окно
{
    //setlocale( LC_CTYPE, ".1251" );
    //setlocale( LC_MONETARY, ".1251" );
    setlocale( LC_ALL, "" );
}

// ОСНОВНАЯ ФУНКЦИЯ
int main()
{
     // ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ
  char predl[80];    // Введенное предложение
  char predl2[80];    // Введенное предложение
  char *res;            // Результирующее предложение
  char slova[N][N]; // Массив слов в предложении
  char slova2 [N][N]; // Массив 2 слов в предложении
  int  sl=-1, rz=-1;  // Счетчики слов
  char buk[80]; // все буквы алфавита
  char *bs="йцукенгшщзхъфывапролджэячсмитьбю";// Буквы строчные
  char *bz ="ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ";/*  заглавные */
  char *r="`!;:,.?- _";         // Разделительные знаки
//ВЫЗОВ ФУНКЦИЙ НА ИСПОЛНЕНИЕ
    rus();
// Заголовок программы
       Title ();
  // Ввод предложения
       InpPredl(predl);
       InpPredl2(predl2);
  // Выделение из предложения слов
      Select (predl, slova, r, &sl);
      Select (predl2, slova2, r, &rz);

       FindDuplicate(slova, slova2, sl, rz);

    return 0;
}

// ОПИСАНИЕ ИСПЛЬЗУЕМЫХ ФУНКЦИЙ
// Заголовок программы
void Title()
{
  char s[1000];
  AnsiToOem(" Задание\n",s);
  puts (s);

}
// Ввод предложения
void InpPredl(char *s)
{
    char s2[50];
    AnsiToOem("Введите предложение \n",s2);
    puts(s2);
  strcpy (s,"Верите ли вы, что задача решена?");
  // gets (s);
}
void InpPredl2(char *s)
{
    char s2[50];
    AnsiToOem("Введите предложение \n",s2);
    puts(s2);
  strcpy (s,"Верите ли вы, во что нибудь?");
 // gets (s);

}

// Выделение из предложения
void Select(const char *predl, char m[][N], char *sel, int *n)
{
  char *p, *s;

  s=strdup (predl); // Сделать копию исходного предложения
	// так как передается константа, strtok требует
	// внесения изменений при своей работе
  p = strtok (s, sel);
  while (p)
    {
     (*n)++;
     strcpy (m[*n],p);
     p = strtok (NULL, sel);
    }
  free (s);
}
/ Сравнение слов
void FindDuplicate(char slova[][N], char slova2[][N], int sl, int rz)
{
  int i, j;
  char buk[80];
   i = sl; //кол во слов в 1 массиве слов
AnsiToOem("Повторы ",buk);
            puts (buk);



  while (i>=0)
    {
     for(j=0;j< =rz;j++)
      if (!strcmp(slova[i],slova2[j])) {
            AnsiToOem(slova[i],buk);
            puts (buk);
                                } // Печать слова
      i--;
    }

}

Листинг обработок строк в С++

Тема:  Обработка символьных массивов

Задание

Во введенном предложении расположите слова в обратной последовательности. Порядок следования знаков препинания не менять.
В предложении используются русские буквы и знаки.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>

#define N 20

  //  ПРЕДВАРИТЕЛЬНОЕ ОБЪЯВЛЕНИЕ ФУНКЦИЙ
  // Заголовок программы
      void Title();
  // Ввод предложения
      void InpPredl (char predl[]);
  // Выделение из предложения
     void Select(const char *predl, char m[][N],char *sel, int *n);
  // Сборка предложения
     char *Constructor(char slova[][N], char razd[][N], int sl, int rz);
  // Вывод результата
     void OutPredl(char *s1, char *s2);

inline void rus()  // Русификация вывода в консольное окно
{
    //setlocale( LC_CTYPE, ".1251" );
    //setlocale( LC_MONETARY, ".1251" );
    setlocale( LC_ALL, "" );
}

// ОСНОВНАЯ ФУНКЦИЯ
int main()
{
     // ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ
  char predl[80];    // Введенное предложение
  char *res;            // Результирующее предложение
  char slova[N][N]; // Массив слов в предложении
  char razd [N][N]; // Массив разделителей в предложении
  int  sl=-1, rz=-1;  // Счетчики слов и разделителей
  char buk[80]; // все буквы алфавита
  char *bs="йцукенгшщзхъфывапролджэячсмитьбю";// Буквы строчные
  char *bz ="ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ";/*  заглавные */
  char *r="`!;:,.?- _";         // Разделительные знаки
//ВЫЗОВ ФУНКЦИЙ НА ИСПОЛНЕНИЕ
    rus();
// Заголовок программы
       Title ();
  // Ввод предложения
       InpPredl (predl);
  // Выделение из предложения слов
      Select (predl, slova, r, &sl);
  // Выделение из предложения разделителей
      strcpy(buk,"");
      strcat (buk, bs);
      strcat (buk, bz);
      Select (predl, razd, buk, &rz);
  // Сборка предложения
      res = Constructor(slova, razd, sl, rz);
  // Вывод результата
     OutPredl (predl, res);
  free (res);
    return 0;
}


// ОПИСАНИЕ ИСПЛЬЗУЕМЫХ ФУНКЦИЙ
// Заголовок программы
void Title()
{
  puts (" Задание  по теме\n");
  
}
// Ввод предложения
void InpPredl(char *s)
{
  puts("Введите предложение \n");
  strcpy (s,"Верите ли вы, что задача решена?");
  // gets (s);
}
// Вывод результата
void OutPredl (char *s1, char *s2)
  {
    puts ("Исходное предложение");
    puts (s1);
    puts (" Результат ");
    puts (s2);
  }
// Выделение из предложения
void Select(const char *predl, char m[][N], char *sel, int *n)
{
  char *p, *s;

  s=strdup (predl); // Сделать копию исходного предложения
	// так как передается константа, strtok требует
	// внесения изменений при своей работе
  p = strtok (s, sel);
  while (p)
    {
     (*n)++;
     strcpy (m[*n],p);
     p = strtok (NULL, sel);
    }
  free (s);
}
// Сборка предложения
char *Constructor(char slova[][N], char razd[][N], int sl, int rz)
{
  int i, j;
  char res[80];
  char *s;
*res=0; // Начальное значение результата
   i = sl;
   j=-1;
  while ((i>=0)||(j<=rz))
    {
      if ((i>=0)) strcat (res, slova[i]); // Добавление слова
      i--;
      j++;
      if ((j<=rz)) strcat (res, razd[j]); // Добавление знаков
    }
  s = strdup (res);
  return s;
}

Листинг задания на обработку одномерных массивов

Тема:  Обработка одномерных массивов

Задание

Заполнить одномерный массив неповторяющимися числами в диапазоне от -30 до +70. Распечатать одномерный массив. Найти минимальное значение в массиве и его индекс. Сделать дубликат массива в динамической области памяти. Провести сортировку массива-дубликата методом прямого поиска. Распечатать результат сортировки. Удалить дубликат из динамической памяти.

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>

#define   N 15

// 1. Инициализация генератора случайных чисел
void Randomize()
{
    srand(time(0));
}
//2. Генератор случайного числа в диапазоне от 0 до range
int Random(int range)
{
    return (rand() % range);
}
// 3. Проверка повторения случайного числа
// c -  указатель начала  массива, n - индекс нового элемента
int Test_Repetition(int *c, int n)
{ int x, j;
    x = 0;       // Считаем, что значение новое
    // Цикл сравнения со всеми предыдущими
    for (j=0; j<n; j++)
        if (*(c+n)==*(c+j))
            {
                x = 1; // Элементы совпали
                break;
            }
    return x;
}
// 4. Добавить новый элемент
// с - указатель начала  массива, n - номер нового элемента
// range1, range2 – левая и правая границы диапазона
void New_Item(int *c, int n, int range1, int range2)
{   int x = 0; // Элементы массива разные
    do
    {
        c[n] = Random(range2 - range1) + range1; // Новое значение
        x =Test_Repetition(c,n); // Проверка на повторение
    }
    while (x==1); // Повторять, когда элементы совпали
}
// 5. Заполнение одномерного массива
// c - массив, n - количество элементов
void Filling (int *c, int n, int range1, int range2)
{       int  i;
    c[0]=Random (range2 - range1) + range1; // Элемент с индексом 0.
    // Цикл заполнения массива
    for (i=1;i<n; i++)  // Цикл заполнения элементов значениями
        New_Item(c, i, range1, range2);
}
// 6. Распечатка одномерного массива
void Print(int *c, int n)
{   int i;
    for (i=0; i<n; i++)
        printf("%4d",c[i]);
    puts(""); // Переход на новую строку
}
// 7. Поиск минимального значения
// с – указатель на начало одномерного массива,
// n - количество элементов массива,
// index – указатель на индекс минимума
int Min(int *c, int n, int *index)
{ int i, min;
    min = c[0]; // Начальное значение минимума
    (*index) = 0; // Начальное значение индекса минимума
    for  ( i=1; i<n; i++ )
        if (c[i]<min)
            {
                min = c[i];
                (*index) = i;
            }
    return min;
}
// 8. Создание дубликата массива в динамической памяти
int * Copy (int *c, int n)
{ int *m, i;
// Резервирование памяти под дубликат массива
    m = (int*)malloc(sizeof(int)*n);
    // Копирование массива
    for ( i = 0; i<n; i++ ) m[i] = c[i];
    // Функция возвращает адрес нового массива
    return m;
}
// 9. Обмен элементов местами в массиве
void Exchange (int *c, int n, int k)
{ int tmp; //Переменная для временного хранения данных
    tmp = c[n];
    c[n] = c[k];
    c[k] = tmp;
}
// 10 .Сортировка методом прямого поиска
void SearchSort ( int *c, int n )
{ int i, min, indexMin; int *p;
     for ( i=0; i<n-1; i++) // Определить массив с индексами от i до n
        {  p = (c+i); // Задать адрес начала массива
             min = Min (p, n-i, &indexMin); // Найти минимум в массиве
            // Обменять местами минимальный элемент с первым
            Exchange ( p, 0, indexMin );        }
}

inline void Rus()  // Русификация вывода в консольное окно
{
    setlocale( LC_CTYPE, ".1251" );
}

void Title()
{
    puts("");
    puts("Задание:\n");
}

// Главная функция
int main()
{
    int m[N];
    int min, IndexMin;
    int *Duplicate;

    Rus();
    Randomize();
    Title();
    puts("\nЗаполнение массива");
    Filling(m,N,-30,70);
    puts("\nРаспечатка массива\n");
    Print (m,N);
    puts("\nМинимальное значение массива\n");
    min = Min(m,N,&IndexMin);
    printf("min = %d его индекс = %d \n", min, IndexMin);
    puts("\nСоздание дубликата массива\n");
    Duplicate = Copy(m,N);
    puts("\nРаспечатка дубликата массива\n");
    Print (Duplicate,N);
    puts("\nСортировка дубликата методом прямого поиска");
    SearchSort(Duplicate,N);
    puts("\nРаспечатка дубликата массива после сортировки\n");
    Print (Duplicate,N);
    puts("\nУдаление дубликата");
    free(Duplicate);
    return 0;
}

Функции и массивы в С++

Тема: Обработка одномерных массивов ( с использованием функций)

Задание

Заполнить два массива, размером 20 и 30 элементов, соответственно, случайными целыми числами в диапазоне от –50 до 50. Из полученных двух массивов создайте два массива отдельно отрицательных и положительных чисел. Проведите сортировку полученных массивов по возрастанию. Для контроля результата сделайте распечатку массивов, в том числе исходного.
Сортировки проведите тремя методами. При использовании каждого из методов желательно использовать свой массив. Если количество массивов меньше трех, то один из массивов перед сортировкой надо скопировать в дополнительный массив и провести его сортировку.

Листинг 2 обработка массивов через функции.

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#define   Nx 20
#define   Ny 30
#define   Nres 50

inline void rus()  // Русификация вывода в консольное окно
{
    setlocale( LC_CTYPE, ".1251" );
    setlocale( LC_MONETARY, ".1251" );

}
void randomize()
{
    srand(time(0));
}

unsigned int random(int range)
{
    return (rand() % range);
}
void CreateMassiv(int *c, int n, int Range)
{
    int i;
     for (i=0;i<n;i++)  {        /* i - is a namber of row       */
      *(c+i) = -50+random(Range);
                       }
}

void PrintMassiv(int *c, int from, int n)
{
    int i;
     for (i=from;i<n;i++)  {        /* i - is a namber of row       */
      printf("%d ",(*(c+i)));
                       }
}

void MoveToMassiv(int *c,int *po, int *ot, int n, int *p, int *o)
{
    int i;
  for (i=0;i<n;i++)  {        /* i - is a namber of row       */
      if (*(c+i)>0) {*(po+(*p))=*(c+i);(*p)++;}
      if (*(c+i)<0) {*(ot+(*o))=*(c+i);(*o)++;}
                    }
}

void CopyMassiv(int *from, int *to, int n)
{
    int i;
     for (i=0; i<n; i++)
       *(to+i+1)=*(from+i);

}
void Sort1Massiv(int *c, int n)
{
    int i,j;
         for ( j=0; j<n-1;j++)
{

    for ( i=0; i<n-1;i++)
    {
        if (*(c+i)>*(c+i+1))
       {
           int temp = *(c+i);
           *(c+i) = *(c+i+1);
           *(c+i+1)=temp;
       }
    }
}
}
/* Сортировка методом прямого поиска */
void Sort2Massiv(int *c, int n)
{
    int i,j;
   int m,min;
  for (i=0;i<n-1;i++) /* в переменной i - индекс первого элемента
   массива, то есть массив от c[i] до c[N] */
    {  /* Найти минимум в массиве от i-того до N-ного */
      m=i; min=(*c+i); /* m-индекс минимума, min-значение минимума */
      for (j=i+1;j<n; j++) /* Поиск в оставшейся части массива */
 {
    if (*(c+j)<min)  /* Найдено новое значение минимума? */
      { min=*(c+j); m=j; } /* Запомнить минимум и его индекс */
 }
      /* Обменять первый (i-ый) и минимум (m-ый) местами */
      *(c+m)=*(c+i); *(c+i)=min;
    }
}
void Sort3Massiv(int *c, int n)
{
     int i,m=0;
/* Сортировка методом прямого включения */
  for (i=2; i<=n; i++) /* в переменной i-индекс включаемого элемента */
    {       /* включение i-того элемента */
      m=i; // Начальное значение индекса цикла включения
      *c=*(c+i); // Установка барьера
      while (*(c+m)<*(c+m-1)) // включение
  { //  Обмен с предыдущим элементом местами
      int tmp   = *(c+m);  *(c+m)  = *(c+m-1); *(c+m-1)= tmp;
      m--; // включение идет к началу массива
 };
    };
}

int main()
{

    int  i, j, range;
    rus();
    randomize();
    int x[Nx];
    int y[Ny];
    int pol[Nres];
    int otr[Nres];
    int pol2[Nres];
    range=100;
   // Создаем одномерный массив
  CreateMassiv(x, Nx, range);
   // Вывод одномерного массива
  printf("Распечатка массива \n");
  PrintMassiv(x,0,Nx);
   // Создаем одномерный массив
  CreateMassiv(y, Ny, range);
  // Вывод одномерного массива
  printf("\n Распечатка массива \n");
  PrintMassiv(y,0,Ny);

// раскидываем массив х и у
int jpol=0, jotr=0;
MoveToMassiv(x,pol,otr, Nx, &jpol, &jotr);
MoveToMassiv(y,pol,otr, Ny, &jpol, &jotr);
 // Создаем доп массив для сортировки (по заданию)
CopyMassiv(pol, pol2, jpol);

//сортировка массива pol
if (jpol>=1) { //если в массиве больше 1 елемента
 Sort1Massiv(pol, jpol);
           }
//сортировка массива otr
if (jotr>=1) { //если в массиве больше 1 елемента
 Sort2Massiv(otr,jotr);
}

//сортировка массива pol2
if (jpol>=1) {//если в массиве больше 1 елемента
 Sort3Massiv(pol2, jpol);
    }

  // Вывод одномерных массивов
  printf("\n Распечатка массива otr \n");
  PrintMassiv(otr,0,jotr);

    printf("\n Распечатка массива pol \n");
  PrintMassiv(pol,0,jpol);

  printf("\n Распечатка массива pol2 \n");
  PrintMassiv(pol2,1,jpol+1);

 return 0;
}

Листинг 2 обработка массивов без функций здесь