Програмен език C++
Част 20

Масиви от стрингове
(Arrays of Strings)

(съдържание)

Масивите от стрингове са обичайна структура, която се използва за запазване на имена, пароли, имена на файлове и други поредици от символи.

1. Дефиниция на масив от стрингове. Тъй като стрингът е масив от символи, на практика масивът от стрингове представлява масив от масив от символи. Ако искаме да запазим 10 имена от максимум 20 символи, то записваме следната дефиниция.

 char names[10][20];   // array of 10 strings

Обърнете внимание, че броят на стринговете (в случая 10) се дава с първото число в първите средни скоби. Към отделен стринг, например с този с номер j, се обръщаме с names[j]: не забравяйте, че първият стринг има номер 0, т.е. този с номер j ще е фактически j+1 подред. Следният код позволява вкарването на тези 10 имена в програмата (или по-малко от десет, ако последният въведен стринг има нула символа):

for (j = 0; j < 10; j++)
{
  cout << “Enter name (or press Enter to exit loop): ”;
  cin.get(names[j], 10);
  if (strlen(names[j]) == 0)    // if user presses [Enter],
     break;                     // exit from loop
}

2. Инициализиране на масив от стрингове. Вие може да инициализирате вашите стрингове още в момента, когато ги създавате. Ето един пример за инициализация на имената на дните от седмицата:

const int MAX = 10;     // maximum length of day name, +1
const int DPW = 7;      // days per week

// array of day names
const char day_name[DPW][MAX] = { "Sunday", "Monday", "Tuesday",
                                  "Wednesday", "Thursday", "Friday",
                                  "Saturday"};

Стринговите константи са разлени със запетайки и са затворени в големи скоби. Обърнете внимание на const в дефиницията, което е уместно, защото тези имена на дните на седмицата не се променят в хода на програмата.

3. Пример за клас, който работи с масив от стрингове. Този пример е взет от книгата на Лафоор [1]. Обърнете внимание, че константата MAX е равна на десет, т.е. с единица по-голяма от дължината на най-дългото име ("Wednesday"), за да има място за нулевият символ, '\0', в масива -- за нулевия символ вижте този материал.

За да не се дублира във всеки един обект структурата day_name, тя е дефинирана като външна променлива (external variable), която е достъпна във всяка една точка на тази програма. Същият ефект може да се постигне и чрез дефинирането на day_name в класа, но като статична променлива (static variable) - с тази дефиниция ще се запознаем в следващите лекции. Ето и пълният код на програмата.

// weekdays.cpp
// creates a class of days of the week objects

#include <iostream.h>
#include <string.h>     // for stricmp()
#include <conio.h>      // for getch()

const int MAX = 10;     // maximum length of day name, +1
const int DPW = 7;      // days per week

// array of day names
const char day_name[DPW][MAX] = { "Sunday", "Monday", "Tuesday",
                                  "Wednesday","Thursday", "Friday",
                                  "Saturday"};

class weekday                     // class of day names
{
  private:
    int day_number;                // Sunday = 0, etc.

  public:
    void inday()                   // user inputs day name
    {
      char tempday[MAX];           // holds user input
      int gotit = 0;               // match found? (0 = false)
      int j;                       // loop variable

      while( !gotit )              // cycle until user enters
      {                            // a correct name
        cout << "Enter day of week (e.g., Friday): ";

        cin >> tempday;

        for (j = 0; j < DPW; j++)       // compare user input
        {                          // with list of names
          if (stricmp(tempday, day_name[j]) == 0)
          {                        // if there's a match,
            gotit = 1;             // set flag,
            break;                 // break out of for loop
          }
        }  // end for

        day_number = j;            // record what day it was
      }  // end while
    }  // end inday()

    void outday()                  // display the day name
    {
      cout << day_name[day_number];
    }

    void outnumber()               // display the day number
    {
      cout << (day_number + 1);
    }

    void add(int days)             // add days to
    {                              // this weekday
      day_number += days;          // add days
      day_number %= DPW;           // ensure not > 7
    }
};  // end weekdays class

////////////////////////////////////////////////////////////////
void main()
{
  weekday wd;                      // make a weekday object

  cout << "What day is it?" << endl;
  wd.inday();                      // user gives it a value

  cout << "You entered ";
  wd.outday();                     // display its day name

  cout << "\nThat's day number ";
  wd.outnumber();                  // display its day number

  wd.add(10);                      // add 10 days to it
  cout << "\nTen days later is ";
  wd.outday();                     // display its day name

  // added to stop the output onto the monitor
  getch();
}   // main()

В класа има една променлива, day_number, която показва номера на деня (обърнете внимание, че неделя е с номер нула!) и четири функции на класа: inday(), outday(), outnumber() и add(int days). Първата функция служи за вкарване на името на деня, който се избира от потребителя, втората разпечатва името на деня на екрана в зависимост от неговия номер, третата показва номерът на деня, като стартира от единица за неделя, а четвъртата "събира" число към номера на деня, т.е. на практика изчислява кой ден от седмицата се пада след това число дни.

В главната програма, main(), се създава обект от класа weekday, вкарва се от потребителя името на деня от седмицата, програмата изписва името и след това поредния номер на този ден и накрая изчислява кой ден е след десет дни (wd.add(10);) и изписва името на този ден на екрана.

4. Някои нови оператори и функции в програмата от т. 3. Във функцията на класа inday() се използва библиотечната функция stricmp(tempday, day_name[j]), която сравнява двата стринга tempday и day_name[j] и връща  0,  ако те са еднакви. Тя прилича на функцията strcmp, но за разлика от нея тя не прави разлика между големи и малки букви (ignores case) и за нея двата стринга "Monday" и "monday" са еднакви.

Друг нов момент е във функцията add(int days), където така нареченият аритметичен оператор за присвояване (Arithmetic Assignment Operator) +=, добавя дясната си част към лявата си част. Т.е. day_number += days; е еквивалентно на day_number = day_number + days;, а day_number %= DPW; - на day_number = day_number%DPW;: не забравяйте, че % намира остатъка на делене на лявата си част на дясната си част.

В C++ има още няколко такива оператора:

a += b;    // same as a = a + b
a -= b;    // same as a = a - b
a *= b;    // same as a = a * b
a /= b;    // same as a = a / b
a %= b;    // same as a = a % b

Резултатът от изпълнение на програмата е следният (при зададен "понеделник"):

What day is it?
Enter day of week (e.g., Friday): monday
You entered Monday
That's day number 2
Ten days later is Thursday

Аритметичните оператори за присвояване правят кода по-прегледен и по-къс, затова се използват масово от програмистите на C++.

В следващия материал от поредицата ще се запознаем с още две нови структури от данни -- изброения тип (enum) и логическия тип (bool).

.
(съдържание)
.
Литература
.
[1] Robert Lafore; C++ Interactive Course. Waite Group Press, Macmillan Computer Publishing, 1996.

Автор: Проф. Процесор Аритметиков

[ това е материал от брой 22 от август 2008 г. на списание "Коснос" www.kosnos.com ]

Keywords: С++,  OOP programming , C++ , Classes , Inheritance , Reusability , Creating New Data Types , Polymorphism and Overloading
Ключови думи: клас , обект, обектно ориентирано програмиране , полиморфизъм switch if else ?