14 Haziran 2017 Çarşamba

smatch Sınıfı

Giriş
Şu satırı dahil ederiz.
#include <regex>
smatch aslında match_results sınıfının gerçekleştirimi.
smatch std::string için kullanılır. cmatch ise char için kullanılır.

Sınıf tüm eşleşmeyi ve yakalanan grupları saklar. regex_search veya regex_match ile kullanılır.
str(), position(), length() gibi metodları vardır. Yakalanan gruplara [1] [2] şeklinde erişilebilir.

operator [0] - tüm eşleşme
smatch[0] tüm eşleşmeyi verir. Çıktı olarak hello ve world alırız.
string str = "hello the3re world";
string exp = "\\b[a-zA-Z]+\\b";
regex r (exp); 

smatch matches;
while (regex_search(str, matches, r)) {
  std::cout << matches[0] << std::endl;
  str = matches.suffix().str();
}
operator [1], operator [1] - yakalama grupları
Elimizde iki tane yakalama grubu olan regex olsun
std::regex r ("...(...),...(...)");
Eşleşme başarılı olsun
std::string const str = "..."

std::smatch matches;
if (std::regex_search(str, matches, r)) {...}
Yakalanan grupları görmek için şöyle yaparız.
std::cout << "..." << matches [1] 
          << "..." << matches [2];
Eğer yakalama grubu 0 veya 1 tane ise şöyle yaparız. Gerçekten yakalama olup olmadığını kontrol etmek için şöyle yaparız.
std::string s = ...;

std::regex re(R"regex((\d+)([GMKgmk]){0,1})regex");
std::smatch match;
bool matched = std::regex_match(s, match, re);
if(!matched) {
  throw ...;
}
if (match[2].matched)
{
  switch (match[2].str().at(0))
  {
    case 'G':
    case 'g':
      std::stoul(match[1].str()) * G);
      break;
    ...
  }
}
suffix metodu
Eşleşme bittikten sonra arkadan kalan kısmı verir. Şöyle yaparız.
std::string str = ...
std::match_results< std::string::const_iterator > what;

std::regex regex = ...;

while( std::regex_search (str, what, regex ) ){
  str = what.suffix().str();
  ...
}


std::regex_search

Giriş
Şu satırı dahil ederiz.
include <regex>
C++11 ile gelen bu sınıflar çok faydalı. Eskiden GNU ile gelen C tarzı metodları kullanır ve şu satırı dahil ederdik.
#include <regex.h>
String'in bir kısmının verilen regex'e uyup uymadığını true veya false olarak döner. regex_search metodları iki gruba ayrılabilir.

1. Match Result Dönmeyen Metodlar
Bunlar en kolay metodlar. Sadece Çağrı sonucunun true veya false olması bizi ilgilendirir.

1.1 regex_search - iterator
Metodun imzası şöyle
template <class BidirectionalIterator, class charT, class traits>
bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
                  const basic_regex<charT, traits> & e,
                  regex_constants::match_flag_type flags =
                  regex_constants::match_default);
1.2 regex_search - string
İlk parametre üzerinde dolaşılacak string, ikinci parametre ise aranılacak örüntüdür. Şöyle yaparız.

std::string example = "fifth\nsixth\nseventh\neighth\nninth";
std::cout << regex_search(example, std::regex("^s")) << endl;
Sonuç olarak false alırız.

Yanlış kullanımı şöyledir. Bu örnek derlenmez çünkü ikinci parametre std::regex yerine yanlışlıkla std::string olarak kullanılmaya çalışılıyor.
string regexCriteria1 = "...";
string test = "...";
regex_search( test, regexCriteria1 );

2. Match Result Dönen Metodlar

regex_search - string + smatch + regex
Örnek
std::string ile kullanımı şöyledir.
std::regex regexCriteria1 = "...";
std::string str = "...";
std::smatch searchResult;

regex_search( str, searchResult, regexCriteria1 );
Örnek
Şöyle yaparız.
unsigned int match_count( std::string str, const std::string& user_pattern ){
  unsigned int counter = 0;
  std::match_results< std::string::const_iterator > what;

  std::regex regex( user_pattern );

  while( std::regex_search( str, what, regex ) ){
    str = what.suffix().str();
    ++counter;
  }

  return counter;
}


regex_search - iterator + iterator + smatch + regex
Örnek
iterator ile kullanımı şöyledir.
std::regex r = "...";
std::string str = "...";
std::smatch searchResult;

regex_search (str.begin(), str.end(), searchResult, r );
Eğer istenirse regex_search döngü içinde de kullanılabilir. Bu durumda başlangıç konumunu ilerletmek gerekir.

8 Haziran 2017 Perşembe

Static Global ve Local Değişken

static kelimesi
static kelimesi overloaded bir kelime. Değişkenler veya metodlar için kullanılabilir.
Global değişken, lokal değişken, member değişken, global metod, member metod için kullanılabilir.
static global değişken
Açıklaması şöyle
3.6.2 Initialization of non-local variables
...
Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.
Static global değişken program çalışmaya başlamadan yani main metoduna girmeden daha önce yaratılır.
Örnek - char * 
Main metodu çalıştıktan sonra ilklendirmek için şöyle yaparız.
static const char *my_static_string = nullptr;

...

void load_static_string()
{
  if(!my_static_string)
  {
    std::string str = //Read string from file.
    my_static_string = new char[str.size() + 1];
    strncpy(my_static_string, str.data(), str.size() + 1);
  }
}
Örnek - std::vector
Şöyle yaparız.
#include <vector>

std::vector<int> v;

int main()
{
    v.push_back(1);
}
Static Order Initialization Fiasco
Static Order Initialization Fiasco yazısına taşıdım.

static local değişken metod ilk kez çağırıldığında yaratılır
static local değişken yazısına taşıdım.

virtual static değişkenler
Genellikle her sınıfa yeni bir ID vermek için kullanılır. İki tane yöntem gördüm.

1. Her sınıf için static local değişken
İlk yöntem de her sınıfın static local bir ID değişkeni vardır. Bu değişken nesnenin ilk getXXX metodu çağrıldığında ata sınıfın yine static olan sayacı +1 yapılarak atanır. Sınıfların hangi değeri alacağı kontrol edilemez.

Önce bir ata sınıf tanımlanır. Ata sınıfın pure virtual bir metodu ve bir de sayaç görevi gören bir metodu vardır.
class Base {
   public:

      virtual int getCompType() = 0;

   protected:

      static int getNextCompType()
      {
         static int nextType = 0;
         return ++nextType;
      }
 };
Her kalıtan sınıf şöyle bir yöntem izler
class Real1: public Base {
   public:
  static int getCompTypeImpl()
  {
     static int myType = Base::getNextCompType();
     return myType;
  }

  int getCompType() override
  {
     return getCompTypeImpl();
  }
};
2. Her sınıf için static member değişken
Bu yöntemde her sınıfın static bir member değişkeni vardır. Bu değişken global bir sayaçtan yeni değer alır. Sınıfların hangi değeri alacağı kontrol edilemez.

class MyInterface{
virtual int getID() = 0;
};

class MyClass : public MyInterface{
COMPONENT(); //Arayüzü gerçekleştiren macro
} 

SET_ID(MyClass); //cpp dosyasındaki sayaçtan yeni değeri alan macro

#define  COMPONENT()\
static int ID;\//Statik değişken tanımla
int getID(){return ID};//Arayüzü gerçekleştir

#define SET_ID(Component)\
int Component::ID = GetNextID();//GetNextID sayaçtan gelen yeni sayı