Структуры и алгоритмы компьютерной обработки данных

Символьные данные и строки

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

Цель лекции: изучить особенности внутреннего представления символьных данных и строк, научиться выполнять ввод/вывод, просмотр и замену в строках при решении задач на языке C++.

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

Для символьных данных в С++ введен тип char. Описание символьных переменных:

char список_имен_переменных;

Например:

const char c='c'; 
  //символ – занимает один байт, его значение не меняется
char a,b; 
  /*символьные переменные, занимают по одному байту, 
    значения меняются*/
const char *s="Пример строки\n"; 
  //текстовая константа

Строка – это последовательность символов, заключенная в двойные кавычки (" ").

Размещая строку в памяти, транслятор автоматически добавляет в ее конце символ '\0' (нулевой символ или нулевой байт, который является признаком конца строки). В записи строки может быть и один символ: "А" (заключен в двойные кавычки), однако, в отличие от символьной константы 'А' (используются апострофы), длина строки "А" равна 2 байтам.

В языке С++ строка – это пронумерованная последовательность символов (массив символов), она всегда имеет тип ).

(рис 7.1) Представление строки и символа

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

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

char s1[] = "ABCDEF"; //инициализация строки
char s2[]={'A','B','C','D','E','F','\0'};//инициализация строки

Операция вычисления размера (в байтах) sizeof действует для объектов символьного типа и строк.

Пример 1.

// Определение размера строк
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {
  char s1[10]="string1";
  int k=sizeof(s1);
  cout<<s1<<"\t"<<k<<"\n";
  char s2[]="string2";
  k=sizeof(s2);
  cout<<s2<<"\t"<<k<<"\n";
  char s3[]={'s','t','r','i','n','g','3','\0'};
  /*окончание строки '\0' следует соблюдать, формируя 
    в программах строки из отдельных символов*/
  k=sizeof(s3);
  cout<<s3<<"\t"<<k<<"\n";
  char *s4="string4";
  //указатель на строку, ее нельзя изменить
  k=sizeof(s4);
  cout<<s4<<"\t"<<k<<"\n";
  system("pause");
  return 0;
}

Результат выполнения программы:

string1 10 – выделено 10 байтов, в том числе под '\0'

string2 8 – выделено 8 байтов (7 + 1 байт под '\0' )

string3 8 – выделено 8 байтов (7 + 1 байт под '\0' )

Ввод-вывод символьных данных и строк

1) Ввод-вывод одиночного символа

getchar() – функция (без параметров) используется для ввода одиночного символа из входного потока. Она возвращает 1 байт информации (символ) в виде значения типа int. Это сделано для распознавания ситуации, когда при чтении будет достигнут конец файла.

putchar(ch) – функция используется для вывода одиночного символа, то есть помещает в стандартный выходной поток символ ch. Аргументом функции вывода может быть одиночный символ (включая знаки, представляемые управляющими последовательностями), переменная или функция, значением которой является одиночный символ.

Например:

/*Программа считывает из входного потока один символ, а затем выводит его на экран*/
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char ch;
  ch=getchar();
  putchar(ch);
  system("pause");
  return 0;
}

Пример 2. Введите предложение, в конце которого стоит точка, и подсчитайте общее количество символов, отличных от пробела (не считая точки).

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char z; //z - вводимый символ
  int k; //k - количество значащих символов
  printf("Напишите предложение с точкой в конце:\n");
  for (k=0; (z=getchar())!='.';)
  /*выражение z=getchar() заключено в скобки, так как 
    операция присваивания имеет более низкий ранг, 
    чем операция сравнения*/
    if (z!=' ') 
      k++;
  printf("\nКоличество символов=%d",k);
  system("pause");
  return 0;
}

Результат выполнения программы:

Напишите предложение с точкой в конце:
1 2 3 4 5 6 7 8 9 0.
Количество символов=10

2) Ввод-вывод стандартного текстового (символьного) потока

gets(s) – функция, которая считывает строку s из стандартного потока до появления символа '\n', сам символ '\n' в строку не заносится.

puts(s) – функция, которая записывает строку в стандартный поток, добавляя в конец строки символ '\n', в случае удачного завершения возвращает значение больше или равное 0 и отрицательное значение ( EOF = -1 ) в случае ошибки.

Например:

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char s[20];
  gets(s);
  puts(s);
  system("pause");
  return 0;
}

Результат выполнения программы: при вводе строки "123 456 789" чтение данных осуществляется побайтно до символа '\n', то есть в s занесется строка "123 456 789\0" (управляющая последовательность '\0' на экран не выводится, а является признаком конца строки). При выводе строки функция puts возвращает в конце строки дополнительно один символ '\n', следовательно, будет выведена строка "123 456 789\n" (управляющая последовательность '\n' на экран не выводится, а осуществляет перевод курсора на новую строку).

Пример 3. Вычислите длину введенной строки.

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char st[100];
  int i=0;
  puts("Введите строку:");
  gets(st);
  while(st[i++]);
  printf("Длина введенной строки = %i\n",i-1);
  system("pause");
  return 0;
}

3) Стандартные потоки ввода-вывода символьных данных и строк

cin – оператор, который определяет стандартные потоки ввода данных.

cout – оператор, который определяет стандартные потоки вывода данных.

<< – операция записи данных в поток;

>> – операция чтения данных из потока.

Например:

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char s[20];
  cin>>s; //ввод строки из стандартного потока
  cout<<s; //вывод строки в стандартный поток
  system("pause");
  return 0;
}

Результат выполнения программы: при вводе строки "123 456 789" чтение данных осуществляется побайтно до первого пробела, то есть в s занесется только первое слово строки "123\0", следовательно, выведется: "123".

Пример 4. Введите слово и замените в нем все вхождения заглавной латинской 'A' на малую латинскую 'a'. Выведите слово после редактирования.

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char st[80];
  int i;
  cout << "\nВведите слово: ";
  cin >> st;
  for(i=0;st[i]!='\0';i++)
     if (st[i]=='A') st[i]='a';
  cout << "\nСлово после редактирования: "<< st;
  system("pause");
  return 0;
}

4) Форматированный ввод-вывод символьных данных и строк

printf() – функция, осуществляющая форматированный вывод данных.

scanf() – функция, осуществляющая форматированный ввод данных.

%cспецификатор формата ввода-вывода одиночного символа.

%sспецификатор формата ввода-вывода строки символов.

Например:

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char s[20];
  scanf("%s",s); 
  //для строк не используется обращение по адресу 
  printf("%s",s);
  system("pause");
  return 0;
}

Результат выполнения программы: при вводе строки "123 456 789", чтение данных осуществляется побайтно до первого пробела, то есть в строку s занесется только первое слово строки "123\0", следовательно, выведется: "123". Так как s – имя символьного массива, то есть адрес его начального элемента, операция в функции scanf для строк не используется.

Пример 5. Записать введенную строку символов в обратном порядке.

#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char st[80];
  char temp;
  int i,len=0;
  printf("\nВведите строку > ");
  scanf("%s",st);
  while (st[len++]); //вычисление длины строки
  len-=2;//поправка на символ конца строки и нумерацию с нуля
  for(i=0;i<len;i++,len--){
    temp=st[i]; //обмен символов
    st[i]=st[len];
    st[len]=temp;
  }
  printf("\nПолученная строка  > %s",st);
  system("pause");
  return 0;
}

Внутренние коды символов

В языке С++ принято соглашение, что везде, где синтаксис позволяет использовать целые числа, можно использовать и символы, то есть данные типа char, которые при этом представляются числовыми значениями своих внутренних кодов. Такое соглашение позволяет сравнительно просто упорядочивать символы, обращаясь с ними как с целочисленными величинами. Например, внутренние коды десятичных цифр в таблицах кодов ASCII упорядочены по числовым значениям, поэтому несложно перебрать символы десятичных цифр в нужном порядке.

//Печать десятичных цифр и их кодов
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]){
  char z;
  for (z='0'; z<='9'; z++) {
    if (z=='0' || z=='5')
      printf ("\n");
    printf("%c - %x  ",z,z); 
  }
  system("pause");
  return 0;
}

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

Пример 6. Вывести на экран вторую часть таблицы кодировки символов (символы с кодами от 128 до 255). Таблица должна состоять из восьми колонок и шестнадцати строк.

#include "stdafx.h"
#include <iostream>
using namespace std;
#define SM 128
int _tmain(int argc, _TCHAR* argv[]){
  unsigned char ch;
  /*если ch объявить как char, то буквам русского алфавита 
    будут соответствовать отрицательные коды*/
  int i,j;
  printf("Таблица ASCII кодировки символов\n");
  for (i=0; i<16; i++) { // шестнадцать строк
    ch=i+SM;   
    for (j=1; j<=8; j++) { // восемь колонок
      printf ("%4c -%4i",ch,ch);
      ch+=16;
    }
    printf ("\n");
  }
  system("pause");
  return 0;
}

Ключевые термины

Внутренние коды символов – целые числа, однозначно соответствующие символам во внутреннем представлении.

Инициализация строки – определение значения строки.

Размер строки – объем памяти, занимаемой строкой, выраженный в байтах.

Символ конца строки – нулевой байт, являющийся признаком конца строки символов.

Символьная константа – константа типа char.

Символьная переменная – переменная типа char.

Строка – это пронумерованная последовательность символов, заключенная в двойные кавычки.

Краткие итоги

  • Для представления текстовой информации в С++ используются символьные данные и строки.
  • В С++ не определен строковый тип данных, и строка представляется как массив символов.
  • Инициализировать строку можно как массив символов.
  • Признаком конца строки является нулевой символ.
  • Обратиться к элементу строки можно по индексу, который соответствует порядковому номеру элемента.
  • Нумерация элементов строки начинается с нуля. Размер строки определяется количеством входящих в нее символов.
  • В С++ предусмотрены различные способы ввода и вывода одиночных символов и строк: с помощью стандартных функций, с помощью потокового или форматированного ввода/вывода. При считывании строки с клавиатуры признак конца строки добавляется автоматически.
  • Каждому символу однозначно соответствует его внутренний код.
  • Лабораторная работа 7. Символьные данные и строки

    Цель работы: изучить особенности внутреннего представления символьных данных и строк, научиться выполнять ввод/вывод, просмотр и замену в строках при решении задач на языке C++.

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

    Теоретические сведения.

    Ознакомьтесь с материалом лекции 7.

    Задания к лабораторной работе.

    Выполните приведенные ниже задания.

  • Введите предложение, слова в котором разделены пробелами и в конце которого стоит точка. Удалите повторяющиеся пробелы между отдельными словами (оставляя по одному пробелу), выведите отредактированное предложение на экран.
  • Дана строка. Выполните символьный анализ текста. Ниже представлен рекомендуемый вид диалога во время работы программы. Данные, вводимые пользователем, выделены жирным шрифтом.
    Введите строку 
    Город Тула основан в 1946 г. I was burn in Tula in 1991.
    Во введенной строке:
       малых русских букв – 16
       заглавных русских букв – 2
       малых латинских букв – 14
       заглавных латинских букв – 2
       цифровых символов –8
       остальных символов – 14
  • Напишите программу, которая проверяет, является ли введенная с клавиатуры строка целым числом (знак числа не учитывать). Ниже представлен рекомендуемый вид диалога во время работы программы. Данные, вводимые пользователем, выделены жирным шрифтом.
    Введите число: 24.5
    Введенная строка не является целым числом.
  • Введите строку и символ. Определите частоту появления данного символа в строке. Частота вычисляется как отношение количества данных символов в строке к длине всей строки (пробелы учитываются, а символ конца строки не учитывается). Ниже представлен рекомендуемый вид диалога во время работы программы. Данные, вводимые пользователем, выделены жирным шрифтом.
    Введите строку  >  Мама мыла раму.
    Введите символ  >  а
    Частота появления символа 'а' в строке "Мама мыла раму." равна 0,27
  • Указания к выполнению работы.

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

    Следует реализовать каждое задание в соответствии с приведенными этапами:

  • изучить словесную постановку задачи, выделив при этом все виды данных;
  • сформулировать математическую постановку задачи;
  • выбрать метод решения задачи, если это необходимо;
  • разработать графическую схему алгоритма;
  • записать разработанный алгоритм на языке С++;
  • разработать контрольный тест к программе;
  • отладить программу;
  • представить отчет по работе.
  • Требования к отчету.

    Отчет по лабораторной работе должен соответствовать следующей структуре.

  • Титульный лист.
  • Словесная постановка задачи. В этом подразделе проводится полное описание задачи. Описывается суть задачи, анализ входящих в нее физических величин, область их допустимых значений, единицы их измерения, возможные ограничения, анализ условий при которых задача имеет решение (не имеет решения), анализ ожидаемых результатов.
  • Математическая модель. В этом подразделе вводятся математические описания физических величин и математическое описание их взаимодействий. Цель подраздела – представить решаемую задачу в математической формулировке.
  • Алгоритм решения задачи. В подразделе описывается разработка структуры алгоритма, обосновывается абстракция данных, задача разбивается на подзадачи. Схема алгоритма выполняется по ЕСПД (ГОСТ 19.003-80 и ГОСТ 19.002-80).
  • Листинг программы. Подраздел должен содержать текст программы на языке программирования С++, реализованный в среде MS Visual Studio 2010.
  • Контрольный тест. Подраздел содержит наборы исходных данных и полученные в ходе выполнения программы результаты.
  • Выводы по лабораторной работе.
  • Ответы на контрольные вопросы.
  • Контрольные вопросы

  • Почему в С++ не выполняется операция прямого присваивания значения строке?
  • Почему символ и строка, состоящая из одного символа, занимают разный объем памяти?
  • Почему в функции scanf("%s",string); не указывается обращение к переменной по адресу?
  • Допустима ли операция сравнения над символами? Если да, то каким образом определены отношения "больше" и "меньше"?
  • Какая из функций, gets или puts, заносит в поток управляющий символ '\n' и с какой целью?
  • Можно ли выполнить присваивание символьной переменной числового значения? Почему?
  • В чем различия результатов вывода символьной переменной со спецификаторами %d и %c?
  • Страницы:

    Цель лекции: изучить особенности внутреннего представления символьных данных и строк, научиться выполнять ввод/вывод, просмотр и замену в строках при решении задач на языке C++.

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

    Для символьных данных в С++ введен тип char. Описание символьных переменных:

    char список_имен_переменных;

    Например:

    const char c='c'; 
      //символ – занимает один байт, его значение не меняется
    char a,b; 
      /*символьные переменные, занимают по одному байту, 
        значения меняются*/
    const char *s="Пример строки\n"; 
      //текстовая константа

    Строка – это последовательность символов, заключенная в двойные кавычки (" ").

    Размещая строку в памяти, транслятор автоматически добавляет в ее конце символ '\0' (нулевой символ или нулевой байт, который является признаком конца строки). В записи строки может быть и один символ: "А" (заключен в двойные кавычки), однако, в отличие от символьной константы 'А' (используются апострофы), длина строки "А" равна 2 байтам.

    В языке С++ строка – это пронумерованная последовательность символов (массив символов), она всегда имеет тип ).

    (рис 7.1) Представление строки и символа

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

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

    char s1[] = "ABCDEF"; //инициализация строки
    char s2[]={'A','B','C','D','E','F','\0'};//инициализация строки

    Операция вычисления размера (в байтах) sizeof действует для объектов символьного типа и строк.

    Пример 1.

    // Определение размера строк
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]) {
      char s1[10]="string1";
      int k=sizeof(s1);
      cout<<s1<<"\t"<<k<<"\n";
      char s2[]="string2";
      k=sizeof(s2);
      cout<<s2<<"\t"<<k<<"\n";
      char s3[]={'s','t','r','i','n','g','3','\0'};
      /*окончание строки '\0' следует соблюдать, формируя 
        в программах строки из отдельных символов*/
      k=sizeof(s3);
      cout<<s3<<"\t"<<k<<"\n";
      char *s4="string4";
      //указатель на строку, ее нельзя изменить
      k=sizeof(s4);
      cout<<s4<<"\t"<<k<<"\n";
      system("pause");
      return 0;
    }

    Результат выполнения программы:

    string1 10 – выделено 10 байтов, в том числе под '\0'

    string2 8 – выделено 8 байтов (7 + 1 байт под '\0' )

    string3 8 – выделено 8 байтов (7 + 1 байт под '\0' )

    Ввод-вывод символьных данных и строк

    1) Ввод-вывод одиночного символа

    getchar() – функция (без параметров) используется для ввода одиночного символа из входного потока. Она возвращает 1 байт информации (символ) в виде значения типа int. Это сделано для распознавания ситуации, когда при чтении будет достигнут конец файла.

    putchar(ch) – функция используется для вывода одиночного символа, то есть помещает в стандартный выходной поток символ ch. Аргументом функции вывода может быть одиночный символ (включая знаки, представляемые управляющими последовательностями), переменная или функция, значением которой является одиночный символ.

    Например:

    /*Программа считывает из входного потока один символ, а затем выводит его на экран*/
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char ch;
      ch=getchar();
      putchar(ch);
      system("pause");
      return 0;
    }

    Пример 2. Введите предложение, в конце которого стоит точка, и подсчитайте общее количество символов, отличных от пробела (не считая точки).

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char z; //z - вводимый символ
      int k; //k - количество значащих символов
      printf("Напишите предложение с точкой в конце:\n");
      for (k=0; (z=getchar())!='.';)
      /*выражение z=getchar() заключено в скобки, так как 
        операция присваивания имеет более низкий ранг, 
        чем операция сравнения*/
        if (z!=' ') 
          k++;
      printf("\nКоличество символов=%d",k);
      system("pause");
      return 0;
    }

    Результат выполнения программы:

    Напишите предложение с точкой в конце:
    1 2 3 4 5 6 7 8 9 0.
    Количество символов=10

    2) Ввод-вывод стандартного текстового (символьного) потока

    gets(s) – функция, которая считывает строку s из стандартного потока до появления символа '\n', сам символ '\n' в строку не заносится.

    puts(s) – функция, которая записывает строку в стандартный поток, добавляя в конец строки символ '\n', в случае удачного завершения возвращает значение больше или равное 0 и отрицательное значение ( EOF = -1 ) в случае ошибки.

    Например:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char s[20];
      gets(s);
      puts(s);
      system("pause");
      return 0;
    }

    Результат выполнения программы: при вводе строки "123 456 789" чтение данных осуществляется побайтно до символа '\n', то есть в s занесется строка "123 456 789\0" (управляющая последовательность '\0' на экран не выводится, а является признаком конца строки). При выводе строки функция puts возвращает в конце строки дополнительно один символ '\n', следовательно, будет выведена строка "123 456 789\n" (управляющая последовательность '\n' на экран не выводится, а осуществляет перевод курсора на новую строку).

    Пример 3. Вычислите длину введенной строки.

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char st[100];
      int i=0;
      puts("Введите строку:");
      gets(st);
      while(st[i++]);
      printf("Длина введенной строки = %i\n",i-1);
      system("pause");
      return 0;
    }

    3) Стандартные потоки ввода-вывода символьных данных и строк

    cin – оператор, который определяет стандартные потоки ввода данных.

    cout – оператор, который определяет стандартные потоки вывода данных.

    << – операция записи данных в поток;

    >> – операция чтения данных из потока.

    Например:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char s[20];
      cin>>s; //ввод строки из стандартного потока
      cout<<s; //вывод строки в стандартный поток
      system("pause");
      return 0;
    }

    Результат выполнения программы: при вводе строки "123 456 789" чтение данных осуществляется побайтно до первого пробела, то есть в s занесется только первое слово строки "123\0", следовательно, выведется: "123".

    Пример 4. Введите слово и замените в нем все вхождения заглавной латинской 'A' на малую латинскую 'a'. Выведите слово после редактирования.

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char st[80];
      int i;
      cout << "\nВведите слово: ";
      cin >> st;
      for(i=0;st[i]!='\0';i++)
         if (st[i]=='A') st[i]='a';
      cout << "\nСлово после редактирования: "<< st;
      system("pause");
      return 0;
    }

    4) Форматированный ввод-вывод символьных данных и строк

    printf() – функция, осуществляющая форматированный вывод данных.

    scanf() – функция, осуществляющая форматированный ввод данных.

    %cспецификатор формата ввода-вывода одиночного символа.

    %sспецификатор формата ввода-вывода строки символов.

    Например:

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char s[20];
      scanf("%s",s); 
      //для строк не используется обращение по адресу 
      printf("%s",s);
      system("pause");
      return 0;
    }

    Результат выполнения программы: при вводе строки "123 456 789", чтение данных осуществляется побайтно до первого пробела, то есть в строку s занесется только первое слово строки "123\0", следовательно, выведется: "123". Так как s – имя символьного массива, то есть адрес его начального элемента, операция в функции scanf для строк не используется.

    Пример 5. Записать введенную строку символов в обратном порядке.

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char st[80];
      char temp;
      int i,len=0;
      printf("\nВведите строку > ");
      scanf("%s",st);
      while (st[len++]); //вычисление длины строки
      len-=2;//поправка на символ конца строки и нумерацию с нуля
      for(i=0;i<len;i++,len--){
        temp=st[i]; //обмен символов
        st[i]=st[len];
        st[len]=temp;
      }
      printf("\nПолученная строка  > %s",st);
      system("pause");
      return 0;
    }

    Внутренние коды символов

    В языке С++ принято соглашение, что везде, где синтаксис позволяет использовать целые числа, можно использовать и символы, то есть данные типа char, которые при этом представляются числовыми значениями своих внутренних кодов. Такое соглашение позволяет сравнительно просто упорядочивать символы, обращаясь с ними как с целочисленными величинами. Например, внутренние коды десятичных цифр в таблицах кодов ASCII упорядочены по числовым значениям, поэтому несложно перебрать символы десятичных цифр в нужном порядке.

    //Печать десятичных цифр и их кодов
    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[]){
      char z;
      for (z='0'; z<='9'; z++) {
        if (z=='0' || z=='5')
          printf ("\n");
        printf("%c - %x  ",z,z); 
      }
      system("pause");
      return 0;
    }

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

    Пример 6. Вывести на экран вторую часть таблицы кодировки символов (символы с кодами от 128 до 255). Таблица должна состоять из восьми колонок и шестнадцати строк.

    #include "stdafx.h"
    #include <iostream>
    using namespace std;
    #define SM 128
    int _tmain(int argc, _TCHAR* argv[]){
      unsigned char ch;
      /*если ch объявить как char, то буквам русского алфавита 
        будут соответствовать отрицательные коды*/
      int i,j;
      printf("Таблица ASCII кодировки символов\n");
      for (i=0; i<16; i++) { // шестнадцать строк
        ch=i+SM;   
        for (j=1; j<=8; j++) { // восемь колонок
          printf ("%4c -%4i",ch,ch);
          ch+=16;
        }
        printf ("\n");
      }
      system("pause");
      return 0;
    }

    Ключевые термины

    Внутренние коды символов – целые числа, однозначно соответствующие символам во внутреннем представлении.

    Инициализация строки – определение значения строки.

    Размер строки – объем памяти, занимаемой строкой, выраженный в байтах.

    Символ конца строки – нулевой байт, являющийся признаком конца строки символов.

    Символьная константа – константа типа char.

    Символьная переменная – переменная типа char.

    Строка – это пронумерованная последовательность символов, заключенная в двойные кавычки.

    Краткие итоги

  • Для представления текстовой информации в С++ используются символьные данные и строки.
  • В С++ не определен строковый тип данных, и строка представляется как массив символов.
  • Инициализировать строку можно как массив символов.
  • Признаком конца строки является нулевой символ.
  • Обратиться к элементу строки можно по индексу, который соответствует порядковому номеру элемента.
  • Нумерация элементов строки начинается с нуля. Размер строки определяется количеством входящих в нее символов.
  • В С++ предусмотрены различные способы ввода и вывода одиночных символов и строк: с помощью стандартных функций, с помощью потокового или форматированного ввода/вывода. При считывании строки с клавиатуры признак конца строки добавляется автоматически.
  • Каждому символу однозначно соответствует его внутренний код.
  • Лабораторная работа 7. Символьные данные и строки

    Цель работы: изучить особенности внутреннего представления символьных данных и строк, научиться выполнять ввод/вывод, просмотр и замену в строках при решении задач на языке C++.

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

    Теоретические сведения.

    Ознакомьтесь с материалом лекции 7.

    Задания к лабораторной работе.

    Выполните приведенные ниже задания.

  • Введите предложение, слова в котором разделены пробелами и в конце которого стоит точка. Удалите повторяющиеся пробелы между отдельными словами (оставляя по одному пробелу), выведите отредактированное предложение на экран.
  • Дана строка. Выполните символьный анализ текста. Ниже представлен рекомендуемый вид диалога во время работы программы. Данные, вводимые пользователем, выделены жирным шрифтом.
    Введите строку 
    Город Тула основан в 1946 г. I was burn in Tula in 1991.
    Во введенной строке:
       малых русских букв – 16
       заглавных русских букв – 2
       малых латинских букв – 14
       заглавных латинских букв – 2
       цифровых символов –8
       остальных символов – 14
  • Напишите программу, которая проверяет, является ли введенная с клавиатуры строка целым числом (знак числа не учитывать). Ниже представлен рекомендуемый вид диалога во время работы программы. Данные, вводимые пользователем, выделены жирным шрифтом.
    Введите число: 24.5
    Введенная строка не является целым числом.
  • Введите строку и символ. Определите частоту появления данного символа в строке. Частота вычисляется как отношение количества данных символов в строке к длине всей строки (пробелы учитываются, а символ конца строки не учитывается). Ниже представлен рекомендуемый вид диалога во время работы программы. Данные, вводимые пользователем, выделены жирным шрифтом.
    Введите строку  >  Мама мыла раму.
    Введите символ  >  а
    Частота появления символа 'а' в строке "Мама мыла раму." равна 0,27
  • Указания к выполнению работы.

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

    Следует реализовать каждое задание в соответствии с приведенными этапами:

  • изучить словесную постановку задачи, выделив при этом все виды данных;
  • сформулировать математическую постановку задачи;
  • выбрать метод решения задачи, если это необходимо;
  • разработать графическую схему алгоритма;
  • записать разработанный алгоритм на языке С++;
  • разработать контрольный тест к программе;
  • отладить программу;
  • представить отчет по работе.
  • Требования к отчету.

    Отчет по лабораторной работе должен соответствовать следующей структуре.

  • Титульный лист.
  • Словесная постановка задачи. В этом подразделе проводится полное описание задачи. Описывается суть задачи, анализ входящих в нее физических величин, область их допустимых значений, единицы их измерения, возможные ограничения, анализ условий при которых задача имеет решение (не имеет решения), анализ ожидаемых результатов.
  • Математическая модель. В этом подразделе вводятся математические описания физических величин и математическое описание их взаимодействий. Цель подраздела – представить решаемую задачу в математической формулировке.
  • Алгоритм решения задачи. В подразделе описывается разработка структуры алгоритма, обосновывается абстракция данных, задача разбивается на подзадачи. Схема алгоритма выполняется по ЕСПД (ГОСТ 19.003-80 и ГОСТ 19.002-80).
  • Листинг программы. Подраздел должен содержать текст программы на языке программирования С++, реализованный в среде MS Visual Studio 2010.
  • Контрольный тест. Подраздел содержит наборы исходных данных и полученные в ходе выполнения программы результаты.
  • Выводы по лабораторной работе.
  • Ответы на контрольные вопросы.
  • Контрольные вопросы

  • Почему в С++ не выполняется операция прямого присваивания значения строке?
  • Почему символ и строка, состоящая из одного символа, занимают разный объем памяти?
  • Почему в функции scanf("%s",string); не указывается обращение к переменной по адресу?
  • Допустима ли операция сравнения над символами? Если да, то каким образом определены отношения "больше" и "меньше"?
  • Какая из функций, gets или puts, заносит в поток управляющий символ '\n' и с какой целью?
  • Можно ли выполнить присваивание символьной переменной числового значения? Почему?
  • В чем различия результатов вывода символьной переменной со спецификаторами %d и %c?
  • Вернуться к учебному плану