Обработка строк: стандартная библиотека string.h

Функции обработки строк в Cи

В программе строки могут определяться следующим образом:

  • как строковые константы;
  • как массивы символов;
  • через указатель на символьный тип;
  • как массивы строк.

Кроме того, должно быть предусмотрено выделение памяти для хранения строки.

Любая последовательность символов, заключенная в двойные кавычки "", рассматривается как строковая константа.

Для корректного вывода любая строка должна заканчиваться нуль-символом '\0', целочисленное значение которого равно 0. При объявлении строковой константы нуль-символ добавляется к ней автоматически. Так, последовательность символов, представляющая собой строковую константу, будет размещена в оперативной памяти компьютера, включая нулевой байт.

Под хранение строки выделяются последовательно идущие ячейки оперативной памяти. Таким образом, строка представляет собой массив символов. Для хранения кода каждого символа строки отводится 1 байт.

Для помещения в строковую константу некоторых служебных символов используются символьные комбинации. Так, если необходимо включить в строку символ двойной кавычки, ему должен предшествовать символ "обратный слеш": '\"'.

Строковые константы размещаются в статической памяти. Начальный адрес последовательности символов в двойных кавычках трактуется как адрес строки. Строковые константы часто используются для осуществления диалога с пользователем в таких функциях, как printf().

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

 
char m[82];

Компилятор также может самостоятельно определить размер массива символов, если инициализация массива задана при объявлении строковой константой:

 
 
char m2[]="Горные вершины спят во тьме ночной.";
char m3[]={'Т','и','х','и','е',' ','д','о','л','и','н','ы',' ','п','о','л','н','ы',' ','с','в','е','ж','е','й',' ','м','г','л','о','й','\0'};

В этом случае имена m2 и m3 являются указателями на первые элементы массивов:

  • m2        эквивалентно &m2[0]
  • m2[0]     эквивалентно 'Г'
  • m2[1]     эквивалентно 'o'
  • m3        эквивалентно &m3[0]
  • m3[2]     эквивалентно 'x'

При объявлении массива символов и инициализации его строковой константой можно явно указать размер массива, но указанный размер массива должен быть больше, чем размер инициализирующей строковой константы:

 
char m2[80]=&qout;Горные вершины спят во тьме ночной.&qout;;

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

 
char *m4;

В этом случае объявление массива переменной m4 может быть присвоен адрес массива:

 
 
 
m4 = m3;
*m4       эквивалентно m3[0]=‘Т’
*(m4+1)   эквивалентно m3[1]=‘и’

Здесь m3 является константой-указателем. Нельзя изменить m3, так как это означало бы изменение положения (адреса) массива в памяти, в отличие от m4.

Для указателя можно использовать операцию увеличения (перемещения на следующий символ):

 
m4++;
 
char m[82];

Компилятор также может самостоятельно определить размер массива символов, если инициализация массива задана при объявлении строковой константой:

 
 
char m2[]="Горные вершины спят во тьме ночной.";
char m3[]={'Т','и','х','и','е',' ','д','о','л','и','н','ы',' ','п','о','л','н','ы',' ','с','в','е','ж','е','й',' ','м','г','л','о','й','\0'};

В этом случае имена m2 и m3 являются указателями на первые элементы массивов:

  • m2        эквивалентно &m2[0]
  • m2[0]     эквивалентно 'Г'
  • m2[1]     эквивалентно 'o'
  • m3        эквивалентно &m3[0]
  • m3[2]     эквивалентно 'x'

При объявлении массива символов и инициализации его строковой константой можно явно указать размер массива, но указанный размер массива должен быть больше, чем размер инициализирующей строковой константы:

 
char m2[80]=&qout;Горные вершины спят во тьме ночной.&qout;;

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

 
char *m4;

В этом случае объявление массива переменной m4 может быть присвоен адрес массива:

 
 
 
m4 = m3;
*m4       эквивалентно m3[0]='Т'
*(m4+1)   эквивалентно m3[1]='и'

Здесь m3 является константой-указателем. Нельзя изменить m3, так как это означало бы изменение положения (адреса) массива в памяти, в отличие от m4.

Для указателя можно использовать операцию увеличения (перемещения на следующий символ):

 
m4++;

Массивы символьных строк

Иногда в программах возникает необходимость описание массива символьных строк. В этом случае можно использовать индекс строки для доступа к нескольким разным строкам.

 
 
char *poet[4] = {"Погиб поэт!", "- невольник чести -",
"Пал," , "оклеветанный молвой."};

В этом случае poet является массивом, состоящим из четырех указателей на символьные строки. Каждая строка символов представляет собой символьный массив, поэтому имеется четыре указателя на массивы. Указатель poet[0] ссылается на первую строку:
*poet[0] эквивалентно 'П', *poet[l] эквивалентно '-'.

Инициализация выполняется по правилам, определенным для массивов. Тексты в кавычках эквивалентны инициализации каждой строки в массиве. Запятая разделяет соседние последовательности. Кроме того, можно явно задавать размер строк символов, используя описание, подобное такому:

 
char poet[4][23];

Разница заключается в том, что такая форма задает «прямоугольный» массив, в котором все строки имеют одинаковую длину.

Основные функции стандартной библиотеки string.h

Основные функции стандартной библиотеки string.h приведены в таблице.

Функция Описание
char *strcat(char *s1, char *s2)
присоединяет s2 к s1, возвращает s1
char *strncat(char *s1, char *s2, int n)
присоединяет не более n символов s2 к s1, завершает строку символом '\0', возвращает s1
char *strсpy(char *s1, char *s2)
копирует строку s2 в строку s1, включая '\0', возвращает s1
char *strncpy(char *s1, char *s2, int n)
копирует не более n символов строки s2 в строку s1, возвращает s1;
int strcmp(char *s1, char *s2)
сравнивает s1 и s2, возвращает значение 0, если строки эквивалентны
int strncmp(char *s1, char *s2, int n)
сравнивает не более n символов строк s1 и s2, возвращает значение 0, если начальные n символов строк эквивалентны
int strlen(char *s)
возвращает количество символов в строке s
char *strset(char *s, char c)
заполняет строку s символами, код которых равен значению c, возвращает указатель на строку s
char *strnset(char *s, char c, int n)
заменяет первые n символов строки s символами, код которых равен c, возвращает указатель на строку s

Пример использования функций

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
    char m1[80] = "Первая строка";
    char m2[80] = "Вторая строка";
    char m3[80];
    system("chcp 1251");
    system("cls");
    strncpy(m3, m1, 6);  // не добавляет '\0' в конце строки
    puts("Результат strncpy(m3, m1, 6)");
    puts(m3);
    strcpy(m3, m1);
    puts("Результат strcpy(m3, m1)");
    puts(m3);
    puts("Результат strcmp(m3, m1) равен");
    printf("%d", strcmp(m3, m1));
    strncat(m3, m2, 5);
    puts("Результат strncat(m3, m2, 5)");
    puts(m3);
    strcat(m3, m2);
    puts("Результат strcat(m3, m2)");
    puts(m3);
    puts("Количество символов в строке m1 равно  strlen(m1) : ");
    printf("%d\n", strlen(m1));
    _strnset(m3, 'f', 7);
    puts("Результат strnset(m3, 'f', 7)");
    puts(m3);
    _strset(m3, 'k');
    puts("Результат strnset(m3, 'k')");
    puts(m3);
    getchar();
    return 0;
}

Результат выполнения

108 комментариев к “Функции обработки строк в Cи”

  1. Владимир

    Елена,здравствуйте.Опять не могу решить задачу.Текст слов разделенных пробелами.Вывести самое короткое(самое длинное)слово.
    Код СИ.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <stdio.h>
    #define M 100 
     int main(void
     {int a[M], s[M];
     int z,c,b,i,n,p=M;i=0;n=-1;
         
       while((c=getchar())!=EOF)
     {   n++; //п-число символов введенных.
         a[n]=c;// массив символов.
         if(c==10)c=32;
         if(c==32) {i=n;}// i-число символов в слове(длина слова).
         else continue;
         n=-1;

         for( b=0; b<i;b++)s[b]=i;// массив длин слов.
         for( b=0; b<i;b++)
         if(s[b]<p){p=s[b];}// сравнение длин слов.
         if(a[b]==10){i==p;
         for( z=0; z<p;z++)
           printf ("%c",a[z]);}
        printf (" ");}
            
         }

    Работает не нормально.В чем ошибка? Спасибо.

    1. Елена

      Зачем так сложно сравнивать длины слов?
      Набрали массив из n символов до пробела.
      if(n>max) {max=n; сохраняем слово;}
      То же с минимумом.
      Ещё не забывайте, что переход на новую строку — это пара символов с кодами 13 и 10. На 10 Вы проверили, а про 13 забыли.

  2. Алексей

    Добрый день!
    Есть такой пример:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include < stdio.h >  
    #include < string.h >
    int main (void)
    {    
       
       char str [24]=” test1/test2/test3/test4”;
       char sep [10]=”/”;
       char *istr;

       printf (“Исходная строка: %s\n“, str);
       printf (“Результат разбиения:\n“);   
       istr = strtok (str,sep);

       while (istr != NULL)
       {
          printf (“%s\n”,istr);
          istr = strtok (NULL,sep);
       }

       return 0;
    }

    у меня вопрос как сделать текст вводимый а не фиксированный и символ который он находит не удалять аперед ним ставить пробел.

    1. Елена

      Чтобы вводить строку с клавиатуры, воспользуйтесь функцией gets(str); или gets_s(str, 24); в зависимости от компилятора. А вот чтобы вставить пробел перед символом, нужна ещё одна строка, в которую копируются все символы до пробела, потом пробел, а потом все остальные символы.

  3. Дмитрий

    Здраствуйте! Дана задача: Подсчитать количество букв k в последнем слове данной строки. Алгоритм мне понятен. Единственное не могу на практике обработать массив с конца и сделать так, чтобы обработка заканчивалась на пробеле между словами. Подскажите, пожалуйста

  4. Алексей

    А как в известной строке найти только цифры? Я знаю такой метод: создать строку "0123456789" и по одному символу проверять, находится ли он в этой строке. Как это осуществить в си?

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

  6. Здравствуйте!Здравствуйте! По условиям лабораторной работы нельзя использовать методы класса string.
    Задача: в произвольном тексте в словах с указанными номерами заменить заданную букву на другую заданную букву пользователем.
    В коде программы идет поиск символа только в первом слове, как переходить к следующим словам? я новичок, если можете, прикрепите кусочек кода.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <iostream>
    #include "string.h"
    #include "stdio.h"
    using namespace std;
     
    int main()
    {
        char from, to;
        char text[100],*wbeg, * wend, delim[] = " ;:,.?!"
        cout << "Input text and put '.' at the end: "; cin.getline(text, 100, '.');
        do { cout << "Line is empty! Retry: "; cin.getline(text, 100, '.');} while (strlen(text) == 0);
        int n_delim = strspn(text, delim); // возвращает к-сть разделителей
        wbeg = text + n_delim; // указатель на начало слова
        wend = text + strlen(text); // указатель на конец слова
        n_delim = strcspn(wbeg, delim);//длина первого слова
        
        int count = 1; cout << "Input number of thе word: "int number; cin >> number; 
        while ((wbeg + n_delim <= wend) && (n_delim != 0))
            if (count == number)
            {
                do
                {
                    cout << "Input symbol, that should be changed: "char ch1; cin >> ch1; //запрос буквы
                    char *pos_s = strchr(wbeg, ch1); 
                    if (pos_s == 0) cout << "No symbol!";
                    else if (wbeg + n_delim <= pos_s) 
                        cout << "Input symbol to change one: "char ch2; cin >> ch2;
                        ch2 = &pos_s;
     
                } while (count <= number);
            }
            else cout << "No words with given number!"return 0;
        }
        return 0;
    }
    1. Елена Вставская

      1
      2
      3
      4
      5
      for(int i=0; i<strlen(text); i++)
      {
        if(text[i]=='a')
          text[i] = 'e';
      }

      Заменяем в строке а на е

  7. Здравствуйте! Какой есть аналог функции replace() в string.h замены определенного символа на другой заданный символ?
    Что пришло в голову : использовать memchr, чтобы найти позицию заданного символа для замены, затем использовать функцию memset, чтобы заменить заданный символ на любой другой.
    Например: слова — "hello", заменить "l" на "m". результат — "hemmo".

    1. Елена Вставская

      Просмотреть строку в цикле как массив символов и заменить требуемый символ

      1. нужно реализовать без использования циклов с пробегом по массиву. лишь функции библиотеки string.h

      2. Марина

        Здравствуйте, подскажите, пожалуйста, как заменить несколько символов в строке (например изменить Су на Уус, ту на Уут?

        1. Елена Вставская

          1
          2
          3
          4
          5
          if(s[i]=='C' && s[i+1]=='y')
          {  res[j++]='Y';res[j++]='y';res[j++]='c';
          i=i+1;}
          else
          {res[j++]=s[i];}
  8. Помогите,пожалуйста. Нужно сделать программу которая удаляет все латинские буквы с строки

    1. Елена Вставская

      Нужно сравнить код каждого символа с a и z (большими и маленькими). Если внутри какого-то из этих диапазонов — значит, латинская буква.

  9. Андрей

    Здравствуйте. Скажите, как в строку вставить символ? Пример имеем "258", а нужно "25.8".

    1. Елена Вставская

      Создать новую строку, куда перенести все символы данной и вставить недостающие

      1. Андрей

        Спасибо! Думал более элегантное решение имеется, типа сдвига влево(вправо) с определённого знакоместа от начала строки.

  10. Здраствуйте!
    Намекните, пожалуйста, как сделать так, чтобы в массиве строк, строки типа A1B2 превращались в ABB в динамической памяти. Есть такой код, но здесь результат выводится посимвольно:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    int main(void)
    {
      system("chcp 1251");
       
      int t, i;
      int len1, len2 = 0;
      char* pw, * ps;
      char text[MAX][LEN];

      printf("\nСтроки(конец — пустая строка): \n");

      for (t = 0; t < MAX; t++)
      {    
        gets_s(text[t]);
        if (!*text[t])    /*встретилась пустая строка
        {
          break;
        }      
      }

      printf("\nИзмененные строки:\n");
      for (i = 0; i < t; i++)
          {    
            len1 = strlen(text[i]);
        
            for (pw = text[i]; *pw; pw++)
            {
              if (isalpha(*pw))
              {
                ps = pw + 1;
                if (isdigit(*ps))
                {
                  for (int j = 0; j < (*ps — 48); j++)
                  {
                    putchar(*pw);
                    len2 += 1;
                  }
                }
              }
              pw++;
            }
        
            printf("\nСтрока увеличилась в %.2f.\n\n", (double)len2 / (double)len1);
            len2 = 0;
          }
        
          return 0;  
    }

    Пробовала использовать массив указателей на каждое введенное предложение:

    1
    2
    3
    4
    5
    6
    7
    8
    printf("\nСтроки(конец — пустая строка): \n");
      do {
        gets_s(text);
        if (strcmp(text, "") == 0)
          break;
        mp[k] = _strdup(text);
        k++;
      } while (++k < MAX);

    Но не знаю, как действовать дальше:(

    1. Елена Вставская

      А чем посимвольный вывод не устраивает?
      Можно сформировать строку из символов, а затем ее вывести

      1. По условию нужно именно скопировать строку в динамическую память, там преобразовать и вывести. А я не могу придумать, как это осуществить

        1. Елена Вставская

          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          30
          31
          32
          33
          34
          35
          36
          37
          38
          39
          40
          41
          42
          43
          44
          45
          46
          47
          48
          for (t = 0; t < MAX; t++)
            {
              gets_s(text[t]);
              if (!*text[t]) /*встретилась пустая строка*/
              {
              break;
              }
            }
            char** rez; // массив результирующих строк
            double* size; // массив отношений длин строк
            rez = (char**)malloc(t * sizeof(char*));
            size = (double*)malloc(t * sizeof(double));

            printf("\nИзмененные строки:\n");
            for (i = 0; i < t; i++)
            {
              // считаем длину строки
              int lenz = 0;
              for (int j = 0; j < strlen(text[i]); j++)
              {
                if (isdigit(text[i][j]))
                  lenz += text[i][j] — 48;
              }
              rez[i] = (char*)malloc(lenz); // выделили память под текущую результирующую строку
              size[i] = (double)strlen(text[i]) / lenz; // определили отношение длин
              int k = 0;
              for (pw = text[i]; *pw; pw++)
              {
                if (isalpha(*pw))
                {
                  ps = pw + 1;
                  if (isdigit(*ps))
                  {
                    for (int j = 0; j < (*ps — 48); j++)
                    {
                      rez[i][k++] = *pw; // заполнение результирующей строки
                    }
                  }
                  pw++;
                }
              }
              rez[i][k] = 0; // заканчиваем строку
            }
            for(int i=0; i<t; i++) // вывод получившегося массива
            {
              printf("%s\n", rez[i]);
              printf("\nСтрока увеличилась в %.2f.\n\n", size[i]);
            }

  11. Алекс

    Как создать массив символьных строк, и сделать так, чтобы проходилось по строке массива и смотрело есть ли там третье слово, если есть, вывести слово и номер строки, если нет, вывести что нет.

    1. Елена Вставская

      Пробел и следующая буква — граница слова. Нужно ввести счётчик и сравнивать его с 3.

  12. Роман

    Здравствуйте, у меня вопрос у вашему примеру представленного выше. А что делать с оставшейся памятью, ведь вы создали массив из 80 символов, а ввели намного меньше? У меня задача просто — дана строка из 1 или 30 слов, в каждом слове от 1 до 10 букв, + между словами запятые и точка в конце. То есть я должен создать массив свыше 300 символов.

  13. Здравствуйте! У меня стоит задача, слова, полученные из файла выводить через дефис. Пыталась придумать алгоритм к этому, но что-то не особо получается(именно как сделать алгоритм, который бы выводил через дефис). Не могли бы натолкнуть на дельные мысли? 

    1. У меня есть 2 массива: 1 со знаками препинания и остальными служебными символами, 2 с алфавитом. Я пыталась сделать алгоритм, чтобы шла посимвольная проверка букв, пока не достигнет одного из символов 1 массива, но не знаю как проверить весь массив

      1. Елена Вставская

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

    2. Елена Вставская

      Напечатать слово, потом дефис и так пока слова не кончатся

  14. Алексей

    Здравствуйте, помогите пожалуйста. Мне нужно переставить слова в строках по убыванию количество букв в них, переставляя их вместе с символами-разделителями взятых слева, если символов-разделителей слева нет, то взять их копии справа. Не могу понять, как реализовать это. Не понятно, как привязать длину слова к этому же слову, чтобы их потом отсортировать по длинам.

    1. Елена Вставская

      Когда разделяем строку на слова, ищем границы слов и одновременно считаем количество символов в слове. А потом сравниваем длину слова с теми, которые уже найдены, и помещаем слово на нужное место.
      А вот насчёт разделителей я не совсем поняла

      1. Алексей

        Насчет разделителей: мы?уехали!:домой! Вот строка, переставляем слова по убыванию количества букв в них, при этом слова переставляются вместе с указателями, взятыми слева, если слева их нет, то берутся копии справа. Итогом будет вот такая строка ?уехали!:домой?мы

      2. Алексей

        А если строка будет очень большого размера, то как осуществлять это сравнение длин слов? можно использовать вспомогательный массив и в нем уже сортировать слова по длинам, но не могу понять как потом эти слова вставлять обратно в строку.

  15. Андрей

    Здравствуйте, нужно найти в строке слова, кол-во цифр в которых не менее двух, и вывести их. Как это сделать?

    1. Елена Вставская

      Сначала найти слова. Граница слова — пробел и следующая буква (кроме первого). Потом в слове посчитать количество цифр. Коды цифр последовательные. Поэтому если символ в строке от '0' до'9', то это цифра.

  16. Полина

    Добрый вечер. Как сделать так, чтобы из строки выводились слова с указанным количеством определенных символов? Их как-то нужно переместить в массив слов, насколько я понимаю, но я не соображу, как это сделать

    1. Елена Вставская

      Не обязательно создавать массив. Можно просто находить слова и сразу выводить нужные (использовать массив для хранения символов). Признаком начала слова является пробел и буква после него (кроме первого слова). Потом считаем символы, пока не дойдем до пробела (и переписываем их в другой массив для слова), и если количество символов равно заданному, то выводим слово из массива.

  17. Наташа

    Здравствуйте, помогите, пожалуйста! Совсем не понимаю, как вывести слова в строке, в которых каждая буква входит не менее двух раз. Не могу разобраться, надо ли делить строку на слова, а если и надо, то как? Как убирать слово из строки, которое не соответствует условию. Совсем голову сломала

    1. Елена Вставская

      Признак начала слова — пробел и следующая буква (за исключением первого слова)
      Убирать слово из строки не нужно. Наоборот, если слово устраивает, то вывести его.

  18. Алеся

    ДД! Подскажите, пожалуйста, как создать (объявить) массив, чтоб его элементы содержали слово (или присвоить)? К примеру, имеется массив a, i = 1..n, a[1]="name1", a[2]="name2", .. a[n]="nameN":)Хочу попробовать создать программу типа генератор имён. Я совсем новичок в си :3

    1. Елена Вставская

      1
      2
      3
      4
      5
      6
      7
      8
      9
      #include <stdio.h>
      int main()
      {
        const char* a[] = { "name1", "name2", "name3" };
        for (int i = 0; i < 3; i++)
          printf("%s\n", a[i]);
        getchar();
        return 0;
      }
        1. Елена Вставская

          Точно так же. Только там есть ещё аргумент — строка, которую мы формируем при форматированном выводе.

  19. Андрей

    Здравствуйте, подскажите , пожалуйста, как лучше реализовать данную программу.
    Ввести строку. Вывести её, заменив сокращения на полные слова (т.к. — "так как", т.е. — "то есть", т.д. — "так далее", т.п. — "тому подобное"). Можно использовать английские аналоги. Язык Си.

    1. Елена Вставская

      Нужен массив сокращений и расшифровок. Формируем новую строку из символов данной. Сравниваем последовательность символов строки с сокращением, и если совпали — вставляем в новую строку расшифровку.

  20. Здравствуйте, есть такое задание "Ввести текст (несколько строк) с клавиатуры, признак окончания – слово «and». Данные размещать в динамической области.
    Изменить текст: Переставить строки, так чтобы они располагались по наличию цифр (строки с цифрами – в начале текста, без цифр – в конце), в конце каждой строки отразить её характеристики (информацию, которую возвращает функция.)Вывести текст на экран и отформатировать: Разбить текст на страницы, параметры (длину строки и количество строк) ввести с клавиатуры" ,скажите ,пожалуйста как переставить строки ,вроде бы поняла ,но программа работает раз через.Можете подсказать ход решения этого номера?Спасибо)

    1. Елена Вставская

      А есть ограничение на максимальное количество и длину строк? Если нет, то придется пользоваться списком, и это сильно усложнит задачу

      1. Нет ,это все условие. И все нужно выполнить без использования string ,все через char.Я вроде бы сделала перестановки (возможно не очень корректно ,через 2 вспомогательные строки ,в одну поместила из массива все строки с цифрами ,а в другую-все строки без цифр, а затем объединила их),но получила одну длинную строку, с которой не понятно как теперь сделать разбиение на страницы без разрыва слов.

        1. Елена Вставская

          Лучше сделать массив указателей на строки. И поменять местами эти указатели.

  21. Никита

    Здравствуйте, как можно ввести предложение, заканчивающееся точкой, и разбить его на слова?

    1. Елена Вставская

      Ввести с помощью функции cin.getline(). Разбить на слова — по признаку: текущий символ является буквой, следующий символ не является буквой — значит, это граница слова.

      1. Никита

        А можете показать маленький кусочек кода, хотя бы как описать функцию?

        1. Елена Вставская

          1
          2
          char s[80];
          cin.get(s, 80);

          Чтобы определять английские слова — можно воспользоваться функцией isalfa() для каждого i-го символа введенной строки в цикле.
          Или поставить условие

          1
          if ((s[i] >= 'A' && s[i]<='Z') || (s[i] >= 'a' && s[i] <= 'z')) {буква}
  22. Павел

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

        1. Елена Вставская

          Создать новую строку большей длины и скопировать в нее все требуемые элементы

  23. Алина

    Здравствуйте!
    задание такое "Написать программу вывода первых 15
    триморфных чисел.
    Числа выводить по 5 в строке."
    Как вывеси определенное количество чисел в строке?

    1. Елена Вставская

      Поставить перевод строки после требуемого количества чисел

        1. Елена Вставская

          1
          2
          3
          4
          5
          6
          7
          8
          for(int i=0; i<3; i++)
          {
            for(int j=0; j<5; j++)
            {
              printf("%d ", a[i*5+j]);
            }
            printf("\n");
          }
  24. Здравствуйте. Хочу обратиться с вопросом, как написать что бы функция возвращала слово длиной макс в 15 букв.

  25. Сергей

    Здравствуйте! Я только начал изучать и пытаюсь понять, как можно заменять символы в строке. Пытаюсь заменить все точки на вопросительные знаки. Но меняются символы, только для первого слова из всей строки. Подскажите пожалуйста, что тут не так?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <stdio.h>
    #include <string.h>
    int main()
    {
      char st[256]="";
      printf("Введите строку:");
      scanf("%s\n", &st);
      int k=0;
      while(st[k]!='\0')
    {
        if(st[k] == '.') st[k]='?';
        k++;
    }
      printf(st,k);
      return 0;
    }
    1. Елена Вставская

      scanf() вводит строку до пробела, табуляции или перевода строки.
      Для ввода целой строки с пробелами в Си используется функция gets() или gets_s() (прототип в string.h). В C++ можно использовать cin.getline()

  26. Кристина

    Здравствуйте. В С++ чтобы записать в строке слово и число в цикле, можно сделать так words = "word" + to_string(i). Как такое можно сделать в СИ?

    1. Елена Вставская

      1
      2
      3
      4
      5
      6
      7
      8
      for(int i=0; i<10; i++) {
      words[i][0]='w';
      words[i][1]='o';
      words[i][2]='r';
      words[i][3]='d';
      words[i][4]=0x30+i;
      words[i][5]=0;
      }
  27. Роман

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    #include <stdio.h>
    #include<stdlib.h>
    #include<time.h>

    int main() {
    unsigned int u,i,b=120,b1,b2,g1,g2,g=0;

    unsigned int pro[10];
    unsigned int pro2[45][2]={0};

    srand(time(NULL));
    for(i=0;i<10;i++)
    {
      pro[i]=rand()%100;
      printf("%d ",pro[i]);
    }
    printf("\r\n");

    for(u=0;u<9;u++)
    {
      for(i=u+1;i<10;i++)// в этом блоке все нормально…
      {

        pro2[g][0]= (pro[u]+pro[i]);
        pro2[g][1]=u;
        pro2[g][2]=i;
        printf("[%d][%d]%d ",pro2[g][1],pro2[g][2],pro2[g][0]);// для проверки работы
        g++;
      }
    }
    printf("\r\n g%d\r\n",g);//для проверки работы
    // 3 строки для проверки работы…
    // компилятор MinGW…
    printf("\r\n2\r\n");
      for(i=0;i<44;i++) { printf("[%d][%d] %d ",pro2[i][1], pro2[i][2], pro2[i][0]);}// здесь какая-то лажа происходит с колонкой pro2[][2] после цикла
    printf("\r\n\r\n");

    for(u=0;u<44;u++)
    {
      for(i=u;i<44;i++)
      {
        
        if(pro2[u][0]>pro2[i][0])
        {
          g=pro2[u][0];
          g1=pro2[u][1];
          g2=pro2[u][2];
          pro2[u][0]=pro2[i][0];
          pro2[u][1]=pro2[i][1];
          pro2[u][2]=pro2[i][2];
          pro2[i][0]=g;
          pro2[i][1]=g1;
          pro2[i][2]=g2;
          
        } 
             
      }
     printf("[%d][%d] %d ",pro2[i][1],pro2[i][2], pro2[i][0]);
    }

     printf("\r\n3 \r\n");
     

    for(i=1;i<44;i++)
    {
     //if(b=pro2[i][0]){printf("Ближайшее число %d",pro[i][0]);break;}
     if(b>pro2[i-1][0] && b<(pro2[i][0]) )
     {
       printf("\r\nзнач %d\r\n",pro2[i][0]);
       if((b-pro2[i-1][0])<(pro2[i][0]-b)){printf("ближайшее число %d+%d",pro[pro2[i-1][1]],pro[pro2[i-1][2]]);break;}
       else {printf("ближайшее число %d+%d",pro [pro2[i][1]], pro[pro2[i][2]]);break;}
     }
    }
      return 0;
    }

    не могу найти ошибку,в цикле записи все работает а после в целом столбце берутся неизвестно откуда какие-то данные…

    1. Елена Вставская

      У Вас объявлен массив, в котором 2 колонки с индексами 0 и 1

      1
      unsigned int pro2[45][2]={0};

      А Вы пытаетесь обратиться к элементам третьей колонки: pro2[2]

  28. Валерий

    У меня возникла сложность реализации функции strtok(). А точнее, хочу записать строку в массив строк(mas[4][35]). Слова должны разбиваться с использованием strtok() и записываться в массив построчно. Пробовал, но не получилось, не могу сообразить как нужно. Вывод на консоль происходит верно.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <stdio.h>
    #include <string.h>
    #define DELIM " "
    int main (void)
    {    
      int i = 0;
      char mas[4][35] = {""};
      char str [] = " test1  test2   test3  test4 ";
      char *istr;
      
      printf ("Begin string: [%s]\n", str);
      printf ("Result:\n");

      istr = strtok (str, DELIM);

      while (istr != NULL)
      {
        printf ("[%s]\n", istr);
    // fgets(mas[i], 35, stdin);
    // i++;
        istr = strtok (NULL, DELIM);
      }
    }

    1. Елена Вставская

      Насколько я поняла, должно быть так:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      #include <stdio.h>
      #include <string.h>
      #define DELIM " "
      int main(void)
      {
        int i = 0;
        char mas[4][35] = { "" };
        char str[] = " test1 test2 test3 test4 ";
        char* istr;

        printf("Begin string: [%s]\n", str);
        printf("Result:\n");

        istr = strtok(str, DELIM);
        while (istr != NULL)
        {
          strcpy(mas[i], istr);
          i++;
          istr = strtok(NULL, DELIM);
        }
        for (int z = 0; z < i; z++)
        {
          printf("[%s]\n", mas[z]);
        }
      }

      1. Валерий

        Все понял, спасибо. Всего то нужно было вместо fgets(), strcpy() делать. Но что то не догадался )))

  29. Сергей

    Здравствуйте. Подскажите, как можно обрабатывать строку в виде массива символов по их ASCII кодам? То есть как мне перевести 'a' в 97, а 97 в 'a'?

  30. Собко Виталий

    Подскажите пожалуста
    как сделать функцию, которая читает первые два слова из строки ввода в
    массив (это аргумент функции) и отвергает остальную часть строки. функция должна
    пропускать символы пробела. Определите слово как последовательность символов, не
    содержит символов пробела или табуляции.

    1. Елена Вставская

      Считывать слово можно при помощи функции scanf("%s", word); или cin>>word.
      Остальные слова сами проигнорируются, если этот вызов повторить дважды

  31. Кирилл

    Здравствуйте, подскажите, как обрезать строку, отбросив все символы после точки.

    1. Елена Вставская

      Перебрать в массиве все символы, пока не будет найдена точка. После точки в массив разместить 0 (конец строки)

  32. Татьяна

    Пробую посимвольно записать ввод в строку. Почему-то на коротких строчках до 7 символов работает, а дальше начинает откусывать конец. Подскажите, пожалуйста, что не так?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    main()
    {
    int i=1;
    int c=0;
    char is[]=" ";
    c=getchar();
    while(c!='\n')
    {
         is[i]=c;
         c=getchar();
       i++;
     }
     printf("%d  %s", i, is);
     }
    1. Елена Вставская

      Удивительно, что до 7 символов работает. Вроде после 2 символов должен перестать работать.

      1
      char is[]=" ";

      Для хранения строки выделяется всего 2 байта.

      1
      char is[100]={0};

      Будет работать до 100 символов.

      1. Татьяна

        Теперь возникла другая проблема: в конце переменная i печатается, а строка is не печатается.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        #include<stdio.h>
        main()
        {
        int i=1;
        int c=0;
        char is[100]={0};
        c=getchar();
        while(c!='\n')
        {
             is[i]=c;
             c=getchar();
             i++;
         }
         printf("%d  ", i);
         printf(" %s",  is);
         }
          1. Александр

            int i = 0; По-вашему, строка начинается с символа конец строки.

          2. Елена Вставская

            Нет, строка должна заканчиваться нулем.

  33. Екатерина

    Здравствуйте, можете подсказать что я делаю неправильно?
    На этой строке "printf("%s", n[nomer].list);" останавливается. Выводятся не все строки текста.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    typedef struct node {
      char * data;
      char *list;
      int color;
    } NODE;

    int main()
    {
      FILE *in;
      char *ps, s[1000], *word, *name; 
      int nomer, list[20], i=0;
      in=fopen("dfs.txt","r"); // открыли файл для чтения
      NODE n[100];
        
      while (fgets(s,1000,in)!=NULL)
      {
        ps=s;
        word=strtok(ps," \n");
          printf("%s ",word);
        sscanf(word,"%d",&nomer);
        name=strtok(NULL," \n");
        n[nomer].data=malloc(strlen(name)+1);
        strcpy(n[nomer].data,name);
          printf("%s ",n[nomer].data);
        n[nomer].list=malloc(strlen((char*)list)+1);  
        while ((word=strtok(NULL," \n"))!=NULL)
        { // читать список
          sscanf(word,"%d",&list[i]);
          strcat(n[nomer].list, word);
          i++;
            }
            printf("%s", n[nomer].list);
            printf("\n");
            n[nomer].color=0;
        //printf("%s ",n[nomer].list);
      }
    }

  34. Ангелина

    Здравствуйте, подскажите пожалуйста , как сделать сортировку строк по алфавиту

        1. Елена Вставская

          Чтоб консоль не закрывалась сразу, а ждала нажатия любой кнопки

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

        1. Елена Вставская

          Слово представляет собой массив символов, привем коды букв идут по возрастанию: 'a'<'b'
          Поэтому открываем три цикла

          1
          2
          3
          4
          5
          6
          7
          8
          9
          for(int i=0;i<len-1; i++) // первое слово
            for(int j=i+1;j<len;j++) // второе слово
            {
              for(int k=0; s[i][k]!=0 && s[j][k]!=0; k++)
              {
                if(s[i][k]>s[j][k])
                  swap(s[i],s[j]); // меняем местами строки, функцию надо составить
              }
            }
  35. Добрый вечер.Можете объяснить мне как я могу избавиться от пробела в сроках.
    Например, если у меня есть строка char name = "Hello world!", и чтобы мне вывело "Helloworld!"
    Большое спасибо за ответ!

    1. Елена Вставская

      Убрать пробел в строке в тексте программы.
      А если строка заранее неизвестна, то

      1
      2
      3
      4
      5
      6
      7
      char res[80], s[80];
      cin.getline(s, 80); int j=0;
      for(int i=0; s[i]!=0; i++)
      if(s[i]!=' ')
        {res[j++]=s[i];}
      }
      res[j++]=0;
  36. Руслан

    Помогите плиз с задачей: Создать файл, содержащий произвольные текстовые строки. Подсчитать количество строк, начинающихся с буквы 'Я'.

    С первой частью проблем нет, а вот на второй пока встал.

    1. Елена Вставская

      Работа с файлами описана здесь

      1
      2
      3
      4
      5
      6
      7
      char s[80];
      int count = 0;
      while(fin.getline(s,80))
      {
        if(s[0] == 'Я')
          count++;
      }

      & #039; — это апостроф 🙂
      Может, дойдут руки когда-нибудь исправить этот глюк.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх