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

Язык Си / Функции обработки строк в 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]="Горные вершины спят во тьме ночной.";

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

 
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];


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

Массив строк

Свободный массив

Описание

 
сhar *poet[4];

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

Операции со строками

Большинство операций языка Си, имеющих дело со строками, работает с указателями. Для размещения в оперативной памяти строки символов необходимо:

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

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

 
 
 
char *name;
name = (char*)malloc(10);
scanf("%9s", name);

Для ввода строки использована функция scanf(), причем введенная строка не может превышать 9 символов. Последний символ будет содержать '\0'.

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

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

Для ввода строки, включая пробелы, используется функция

 
char * gets(char *);

или её эквивалент
 
char * gets_s(char *);


В качестве аргумента функции передается указатель на строку, в которую осуществляется ввод. Функция просит пользователя ввести строку, которую она помещает в массив, пока пользователь не нажмет Enter.

Функции вывода строк

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

 
printf("%s", str); // str — указатель на строку

или в сокращенном формате

 
printf(str);


Для вывода строк также может использоваться функция
 
int puts (char *s);

которая печатает строку s и переводит курсор на новую строку (в отличие от printf()). Функция puts() также может использоваться для вывода строковых констант, заключенных в кавычки.

Функция ввода символов

Для ввода символов может использоваться функция

 
char getchar();

которая возвращает значение символа, введенного с клавиатуры. Указанная функция использовалась в рассмотренных ранее примерах для задержки окна консоли после выполнения программы до нажатия клавиши.

Функция вывода символов

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

 
char putchar(char);

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

Пример Посчитать количество введенных символов во введенной строке.
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
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
  char s[80], sym;
  int count, i;
  system("chcp 1251");
  system("cls");
  printf("Введите строку : ");
  gets_s(s);
  printf("Введите символ : ");
  sym = getchar();
  count = 0;
  for (i = 0; s[i] != '\0'; i++)
  {
    if (s[i] == sym)
      count++;
  }
  printf("В строке\n");
  puts(s);      // Вывод строки
  printf("символ ");
  putchar(sym); // Вывод символа
  printf(" встречается %d раз", count);
  getchar(); getchar();
  return 0;
}

Результат выполнения
Количество введенных символов в строке

Основные функции стандартной библиотеки 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;
}

Результат выполнения
Использование функций


Назад: Язык Си

Комментариев к записи: 132

  • Владимир
    Елена,здравствуйте.Опять не могу решить задачу.Текст слов разделенных пробелами.Вывести самое короткое(самое длинное)слово. Код СИ.
    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 (" ");}
            
         }
    Работает не нормально.В чем ошибка? Спасибо.

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

  • Владимир
    Елена, здравствуйте.Опять я забуксовал на книжней задаче. Учу СИ по книге Д.Ритчи.Пытаюсь скомпилировать задачу по строкам в 4-х компилятора ошибки на неё.В авторском варианте ни где запустить не смог.У меня вопрос- книга старая,сменился стандарт СИ или это ещё что-то. И главный вопрос эта задача работает с 2-мя строками или со всеми введенными? Текст задачи.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    #include <stdio.h> 
     #define MAXLINE  1000
     int getline(char line[],int MAXLINE);
     void copy (char to[], char from[]);
         int main () { int len,max;
     char line[MAXLINE];
     char longest[MAXLINE];
    max=0;
     while((len =getline(line,MAXLINE))>0)
    if(len>max){max=len;
    copy(longest,line);}
    if(max>0) printf("%s",longest); 
    return 0; }
    int getline (char s[] ,int lim) {
    int c,i ; 
    for(i=0;i<lim&&(c=getchar())!='\0'&&c!='\n';i++)
    s[i]=c;
    if(c=='\n'){s[i]=c;i++;}
    s[i]='\0'; return i;  }
    void copy(char to[],char from[])
    {int i;i=0;
    while((to[i]=from[i])!='\0') i++;}

  • Владимир
    Елена,здравствуйте.Начал учить СИ и столкнулся с неприступной для меня задачей-как н-количество символов одинаковых и рядом стоящих заменить одним таким же символом? Задача книжная в самом начале,где ещё не дошли до массивов.

    • Как без массивов решать - не знаю, честно скажу. Скажите хотя бы, как хранятся без массива рассматриваемые символы

      • Владимир
        Елена,здравствуйте. Вчера написал сообщение, но оно так и не появляется. Выделенные символы могу выделить, но один потом вернуть не могу. Делаю через getchar i printf. Если не затруднит как реализовать это через массивы. Код не надо- на словах если можно.Спасибо.

        • 1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          #include <stdio.h>
          int main()
          {
            char s[80];
            gets_s(s, 80);
            char t[80];
            t[0] = s[0];
            int k = 1;
            for (int i = 1; s[i] != '\0'; i++)
            {
              if (s[i] == s[i - 1])
                continue;
              t[k++] = s[i];
            }
            t[k++] = '\0';
            printf(t);
            return 0;
          }

          • Владимир
            Елена, спасибо. Всё работает- буду изучать.

      • Владимир
        1
        2
        3
        4
        5
        6
        7
        #include <stdio.h>
         
        int main(void) {int pc;
          int c;
        for(pc=0;(c=getchar())!=EOF;pc=c){
        if(pc==c) continue;
        printf("%c",c);}
          Замена рядом стоящих символов одним без массивов.В DEV++ идет.

  • Алексей
    Добрый день! Есть такой пример:
    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;
    }
    у меня вопрос как сделать текст вводимый а не фиксированный и символ который он находит не удалять аперед ним ставить пробел.

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

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

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

  • Помогите плиз с задачей: дописать символ к строке?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <string>
    #include <iostream>

    using namespace std;

    int main()
    {
        string s;
        char c;
        cout << "Введите слово: ";
        cin >> s;
        cout << "Добавить: ";
        cin >> c;
        s += c;
        cout << "Итог: " << s << endl;
    }

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

    • Елена Вставская
      https://prog-cpp.ru/data-tree/ Тут есть пример со статистикой слов. С буквами можно попробовать сделать по аналогии.

  • Здравствуйте!Здравствуйте! По условиям лабораторной работы нельзя использовать методы класса 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
      2
      3
      4
      5
      for(int i=0; i<strlen(text); i++)
      {
        if(text[i]=='a')
          text[i] = 'e';
      }
      Заменяем в строке а на е

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

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

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

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

        • Елена Вставская
          1
          2
          3
          4
          5
          if(s[i]==&#039;C&#039; &amp;&amp; s[i+1]==&#039;y&#039;)
          {  res[j++]=&#039;Y&#039;;res[j++]=&#039;y&#039;;res[j++]=&#039;c&#039;;
          i=i+1;}
          else
          {res[j++]=s[i];}

  • Помогите,пожалуйста. Нужно сделать программу которая удаляет все латинские буквы с строки

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

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

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

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

  • Здравствуйте я пытлся написать программу чтоб выводились только 16 ричные константы ноу меня не вышло можете помочь ?

    • Елена Вставская
      Формат вывода констант в шестнадцатеричном виде printf("%x", value);

  • Здраствуйте! Намекните, пожалуйста, как сделать так, чтобы в массиве строк, строки типа 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
          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]);
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • Елена Вставская
      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;
      }

      • Спасибо) А вы не знаете, как такое же реализовать через функцию sprintf?

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

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

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

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

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

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

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

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

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

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

        • Елена Вставская
          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')) {буква}

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

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

  • Здравствуйте. Хочу обратиться с вопросом, как написать что бы функция возвращала слово длиной макс в 15 букв.

  • Здравствуйте! Я только начал изучать и пытаюсь понять, как можно заменять символы в строке. Пытаюсь заменить все точки на вопросительные знаки. Но меняются символы, только для первого слова из всей строки. Подскажите пожалуйста, что тут не так?
    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;
    }

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

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

    • Елена Вставская
      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;
      }

  • 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;
    }
    не могу найти ошибку,в цикле записи все работает а после в целом столбце берутся неизвестно откуда какие-то данные...

    • Елена Вставская
      У Вас объявлен массив, в котором 2 колонки с индексами 0 и 1
      1
      unsigned int pro2[45][2]={0};
      А Вы пытаетесь обратиться к элементам третьей колонки: pro2[i][2]

  • Валерий
    У меня возникла сложность реализации функции 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
      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]);
        }
      }

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

  • Алексей
    Добрый день. У меня есть такая проблема. Мне нужно из файла считать в одну строку текст, состоящий из нескольких строк. Не подскажите, как это сделать ?

  • Владимир
    При выходе из функции указатель находится на последнем символе '\0'. Как его оптимально переместить на начало?

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

  • спасибо, как из массива взять сразу же несколько символов на пример; 1012 Мб тут надо взять только первые 4 символа буду рад и благодарен за помощь

  • Думаю стоит конкретизировать разницу между двойными и одинарными кавычками, так как для новичка это не очевидно.

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

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

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

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

  • Татьяна
    Пробую посимвольно записать ввод в строку. Почему-то на коротких строчках до 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);
     }

    • Елена Вставская
      Удивительно, что до 7 символов работает. Вроде после 2 символов должен перестать работать.
      1
      char is[]=" ";
      Для хранения строки выделяется всего 2 байта.
      1
      char is[100]={0};
      Будет работать до 100 символов.

      • Татьяна
        Теперь возникла другая проблема: в конце переменная 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);
         }


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

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

  • Екатерина
    Здравствуйте, можете подсказать что я делаю неправильно? На этой строке "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);
      }
    }

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



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


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

        • Елена Вставская
          Слово представляет собой массив символов, привем коды букв идут по возрастанию: '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]); // меняем местами строки, функцию надо составить
              }
            }

  • Добрый вечер.Можете объяснить мне как я могу избавиться от пробела в сроках. Например, если у меня есть строка char name = "Hello world!", и чтобы мне вывело "Helloworld!" Большое спасибо за ответ!

    • Елена Вставская
      Убрать пробел в строке в тексте программы. А если строка заранее неизвестна, то
      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]!=&#039; &#039;)
        {res[j++]=s[i];}
      }
      res[j++]=0;

      • Николай
        извините руский язик не мой родной .Здраствуйте ,хочу через собсвеную функция считат сколко букви–символь слов имеет.хочу сделат по 2 начина разние .первий сделал второй не успел вот первийй
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        #include<unistd.h>
        #include<stdio.h>
        int myStrlen(char *s)/*char*s или char s[] е едно и също*/
        {
            int len = 0;
            while(*s != 0) {/*докато стигне терминиращ символ*/
                s++; /* *s е първия символ към който е насочен указателя -увеличава се със всяка итерация с 1*/
                len++;
                
            }
            printf("lethg is %d",len);/*отпечатваме дължината*/
            return len; /* функцията връща дължината*/
            
        }
        int main(){
            char*s="Nikolay";/*подаваме стринга*/
            myStrlen(s);/*викаме функцията*/
           sleep(4);/* 4 секунди пауза*/
            return 0;
        }
        второй начен не работает как надо
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        #include <stdio.h>
        #include<unistd.h>
        int myStrlen(char arr[]){
            int n;
            for(n=0;arr !='\0';arr++)
            n++;
            printf("lenthg is %d",n);
            return n;
        }
        int main(){
            char arr[]={'n','i','k'};
            myStrlen(arr);
            sleep(4);
            return 0;
        }
        здес ошибка

  • Добрый день!Помогите решить задачу, буду очень благодарна Дана строка, содержащая от 1 до 30 слов, в каждом из которых от 1 до 10 латинских букв и/или цифр; между соседними словами – не менее одного пробела, за последним словом – точка. Напечатать все слова, содержащие цифры, предварительно преобразовав каждое из них по следующему правилу: переписать слово задом наперед.

    • Елена Вставская
      Не занимаюсь решением учебных задач, поскольку сама являюсь преподавателем. Если есть вопросы - отвечу

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

    • Елена Вставская
      Работа с файлами описана здесь
      1
      2
      3
      4
      5
      6
      7
      char s[80];
      int count = 0;
      while(fin.getline(s,80))
      {
        if(s[0] == &#039;Я&#039;)
          count++;
      }
      & #039; - это апостроф :) Может, дойдут руки когда-нибудь исправить этот глюк.

  • Евгений
    Проверьте, пожалуйста, текст Вашей статьи - тут какая-то вакханалия с кавычками :)

Добавить комментарий

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