Home

ITA - Appunti Cpp 009 - Strings

linux debian mx-linux cpp

Stringhe e Caratteri

Nella libreria standard C++, un carattere è un oggetto che, se trattato in sequenza, può rappresentare del testo.

Funzioni per i caratteri

La libreria che contiene le funzioni per i caratteri è:

Contiene le seguenti funzioni:

controlla se un carattere è alfanumerico isalnum
controlla se un carattere è alfabetico isalpha
controlla se un carattere è minuscolo islower
controlla se un carattere è maiuscolo isupper
controlla se un carattere è una cifra isdigit
controlla se un carattere è un carattere esadecimale isxdigit
controlla se un carattere è un carattere di controllo iscntrl
controlla se un carattere è un carattere grafico isgraph
controlla se un carattere è uno spazio isspace
controlla se un carattere è un carattere vuoto isblank
controlla se un carattere è un carattere stampabile isprint
controlla se un carattere è un carattere di punteggiatura ispunct
converte un carattere in minuscolo tolower
converte un carattere in maiuscolo toupper

Esempio d’uso della libreria <cctype> :

#include <iostream>
#include <cctype>

int main ()
{
    char c = 'c';

    std::cout << "test isalnum :" << std::endl;
    std::cout << "input: " << c << " output: " << isalnum(c) << std::endl;

    std::cout << "test isalpha :" << std::endl;
    std::cout << "input: " << c << " output: " << isalpha(c) << std::endl;

    std::cout << "test isblank :" << std::endl;
    std::cout << "input: " << c << " output: " << isblank(c) << std::endl;

    std::cout << "test iscntrl :" << std::endl;
    std::cout << "input: " << c << " output: " << iscntrl(c) << std::endl;

    std::cout << "test isdigit :" << std::endl;
    std::cout << "input: " << c << " output: " << isdigit(c) << std::endl;

    std::cout << "test isgraph :" << std::endl;
    std::cout << "input: " << c << " output: " << isgraph(c) << std::endl;

    std::cout << "test islower :" << std::endl;
    std::cout << "input: " << c << " output: " << islower(c) << std::endl;

    std::cout << "test isprint :" << std::endl;
    std::cout << "input: " << c << " output: " << isprint(c) << std::endl;

    std::cout << "test ispunct :" << std::endl;
    std::cout << "input: " << c << " output: " << ispunct(c) << std::endl;

    std::cout << "test isspace :" << std::endl;
    std::cout << "input: " << c << " output: " << isspace(c) << std::endl;

    std::cout << "test isupper :" << std::endl;
    std::cout << "input: " << c << " output: " << isupper(c) << std::endl;

    std::cout << "test isxdigit :" << std::endl;
    std::cout << "input: " << c << " output: " << isxdigit(c) << std::endl;

    std::cout << "test tolower :" << std::endl;
    std::cout << "input: " << c << " output: " << tolower(c) << std::endl;

    std::cout << "test toupper :" << std::endl;
    std::cout << "input: " << c << " output: " << toupper(c) << std::endl;
}

Stringhe in stile C

Con stringhe in stile C si intende un array di char:

#include <iostream>
#include <cstring>

int main(){
    const char* my_string_00 {"Hello"}; // questo funziona ma genera un warning
    const char my_string_01[10] {"World"};
    
    std::cout << my_string_00 << " " << my_string_01 << std::endl;

}

Le stringhe in stile C possono essere manipolate con le funzioni contenute nell’header cstring:

Manipolazione delle stringhe  
Copia una stringa in un’altra strcpy
Copia una certa quantità di caratteri da una stringa all’altra strncpy
Concatena due stringhe strcat
Concatena una certa quantità di caratteri di due stringhe strncat
Trasforma una stringa in modo che strcmp produca lo stesso risultato di strcoll strxfrm
Esame della stringa  
Restituisce la lunghezza di una determinata stringa strlen
Confronta due stringhe strcmp
Confronta un certo numero di caratteri di due stringhe strncmp
Confronta due stringhe in base alla locale corrente strcoll
Trova la prima occorrenza di un carattere strchr
Trova l’ultima occorrenza di un carattere strrchr
Restituisce la lunghezza del segmento iniziale massimo costituito solo dai caratteri trovati in un’altra stringa di byte strspn
Restituisce la lunghezza del segmento iniziale massimo costituito solo dai caratteri non trovati in un’altra stringa di byte strcspn
Trova la prima posizione di qualsiasi carattere da un insieme di separatori strpbrk
Trova la prima occorrenza di una sotto stringa di caratteri strstr
Trova il token successivo in una stringa di byte strtok
Manipolazione di array di caratteri  
Cerca in un array la prima occorrenza di un carattere memchr
Confronta due buffer memcmp
Riempie un buffer con un carattere memset
Copia un buffer in un altro memcpy
Sposta un buffer in un altro memmove
Miscellaneo  
Restituisce una versione testuale di un determinato codice di errore strerror

Inoltre la libreria introduce un nuovo tipo:

Tipi  
tipo intero senza segno restituito dall’operatore sizeof size_t

Di seguito l’esempio:

#include <iostream>
#include <iomanip>
#include <cstring>
#include <bitset>
#include <climits>

int main(){
    const char* array_string_00 {"Hello"}; // questo funziona ma genera un warning
    char array_string_01[10] {"World"};
    char array_string_02[10];
    std::size_t mem_size {2};


    std::cout << "test strcpy:" << std::endl;
    std::cout << "\tarray_string_00 bfeore: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_02 bfeore: " << array_string_02 << std::endl;
    // char* strcpy( char* dest, const char* src );
    strcpy(array_string_02, array_string_00);                
    std::cout << "\tarray_string_00 after: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_02 after: " << array_string_02 << std::endl;

    
    std::cout << "test strncpy:" << std::endl;
    std::cout << "\tarray_string_01 bfeore: " << array_string_01 << std::endl;
    std::cout << "\tarray_string_02 bfeore: " << array_string_02 << std::endl;
    // char* strncpy( char* dest, const char* src, std::size_t count );
    strncpy(array_string_02, array_string_01, mem_size);     
    std::cout << "\tarray_string_01 after: " << array_string_01 << std::endl;
    std::cout << "\tarray_string_02 after: " << array_string_02 << std::endl;


    std::cout << "test strcat:" << std::endl;
    std::cout << "\tarray_string_00 bfeore: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_02 bfeore: " << array_string_02 << std::endl;
    // char* strcat( char* dest, const char* src );
    strcat(array_string_02, array_string_00);                
    std::cout << "\tarray_string_00 after: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_02 after: " << array_string_02 << std::endl;

    
    std::cout << "test strncat:" << std::endl;
    std::cout << "\tarray_string_00 bfeore: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_01 bfeore: " << array_string_01 << std::endl;
    // char* strncat( char* dest, const char* src, std::size_t count );
    strncat(array_string_01, array_string_00, mem_size);
    std::cout << "\tarray_string_00 after: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_01 after: " << array_string_01 << std::endl;


    std::cout << "test strxfrm:" << std::endl;
    std::cout << "\tarray_string_00 bfeore: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_02 bfeore: " << array_string_02 << std::endl;
    // std::size_t strxfrm( char* dest, const char* src, std::size_t count );
    strxfrm(array_string_01, array_string_00, mem_size);
    std::cout << "\tarray_string_00 after: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_02 after: " << array_string_02 << std::endl;


    std::cout << "test strlen:" << std::endl;
    // std::size_t strlen( const char* str );
    std::cout << "\tarray_string_00 len: " << strlen(array_string_00) << std::endl;
    std::cout << "\tarray_string_01 len: " << strlen(array_string_01) << std::endl;
    std::cout << "\tarray_string_02 len: " << strlen(array_string_02) << std::endl;
 

    std::cout << "test strcmp:" << std::endl;
    // int strcmp( const char* lhs, const char* rhs );
    std::cout << "\tcompare array_string_00 whit array_string_00: " << strcmp(array_string_00, array_string_00) << std::endl;
    std::cout << "\tcompare array_string_00 whit array_string_01: " << strcmp(array_string_00, array_string_01) << std::endl;
    std::cout << "\tcompare array_string_00 whit array_string_02: " << strcmp(array_string_00, array_string_02) << std::endl;

 
    std::cout << "test strncmp:" << std::endl;
    // int strncmp( const char* lhs, const char* rhs, std::size_t count );
    std::cout << "\tcompare mem_size most array_string_00 whit array_string_00: " << strncmp(array_string_00, array_string_00, mem_size) << std::endl;
    std::cout << "\tcompare mem_size most array_string_00 whit array_string_01: " << strncmp(array_string_00, array_string_01, mem_size) << std::endl;
    std::cout << "\tcompare mem_size most array_string_00 whit array_string_02: " << strncmp(array_string_00, array_string_02, mem_size) << std::endl;
 

    std::cout << "test strcoll:" << std::endl;
    // int strcoll( const char* lhs, const char* rhs );
    std::cout << "\tcompare mem_size most array_string_00 whit array_string_00: " << strcoll(array_string_00, array_string_00) << std::endl;
    std::cout << "\tcompare mem_size most array_string_00 whit array_string_01: " << strcoll(array_string_00, array_string_01) << std::endl;
    std::cout << "\tcompare mem_size most array_string_00 whit array_string_02: " << strcoll(array_string_00, array_string_02) << std::endl;


    strcpy(array_string_01, "testoc");
    std::cout << "test strchr:" << std::endl;
    // char* strchr(       char* str, int ch );
    std::cout << "\tfind char c on array_string_00 at pos: " << strchr(array_string_01, 'c') << std::endl;


    std::cout << "test strrchr:" << std::endl;
    // char* strrchr(       char* str, int ch );
    std::cout << "\tfind char c on array_string_00 at pos: " << strrchr(array_string_01, 'c') << std::endl;


    strcpy(array_string_01, "testoc");
    strcpy(array_string_02, "te");
    std::cout << "test strspn:" << std::endl;
    // size_t strspn( const char* dest, const char* src );
    std::cout << "\t find array_string_02 in  array_string_01 lenght: " << strspn(array_string_01, array_string_02) << std::endl;


    std::cout << "test strcspn:" << std::endl;
    // size_t strspn( const char* dest, const char* src );
    std::cout << "\t find array_string_02 in  array_string_01 lenght: " << strcspn(array_string_01, array_string_02) << std::endl;


    std::cout << "test strpbrk:" << std::endl;
    const char* str = "hello world, friend of mine!";
    const char* sep = " ,!";
    unsigned int cnt = 0;
    do
    {
        str = std::strpbrk(str, sep); // find separator
        std::cout << std::quoted(str) << '\n';
        if (str)
            str += std::strspn(str, sep); // skip separator
        ++cnt; // increment word count
    } while (str && *str);
    std::cout << "There are " << cnt << " words\n";


    strcpy(array_string_01, "testoc");
    strcpy(array_string_02, "to");
    std::cout << "test strstr:" << std::endl;
    // const char* strstr( const char* haystack, const char* needle );
    std::cout << "\t find array_string_02 in  array_string_01 lenght: " << strstr(array_string_01, array_string_02) << std::endl;


    std::cout << "test strtok:" << std::endl;
    // char* strtok( char* str, const char* delim );
    char input[] = "one + two * (three - four)!";
    const char* delimiters = "! +- (*)";
    char* token = std::strtok(input, delimiters);
    while (token)
    {
        std::cout << std::quoted(token) << ' ';
        token = std::strtok(nullptr, delimiters);
    }


    std::cout << "\ntest memchr:" << std::endl;
    // memchr(const void* s, int c, size_t n);    
    const char str_chr[] = "ABCDEFG";
    const int chars[] = {'D', 'd'};
    for (size_t i = 0; i < sizeof chars / (sizeof chars[0]); ++i)
    {
        const int c = chars[i];   
        const void* ps = memchr(str_chr, c, strlen(str_chr));
        ps ? printf ("character '%c'(%i) found: %s\n", c, c, ps)
           : printf ("character '%c'(%i) not found\n", c, c);
    }


    std::cout << "test memcmp:" << std::endl;
    // void* memcpy( void* dest, const void* src, std::size_t count );
    char source_cmp[] = "once upon a daydream...", dest_cmp[4];
    std::cout << "\tsource before: " << source_cmp << std::endl;
    std::cout << "\tdest before: " << dest_cmp << std::endl;
    std::memcpy(dest_cmp, source_cmp, sizeof dest_cmp);
    std::cout << "\tsource after: " << source_cmp << std::endl;
    std::cout << "\tdest after: " << dest_cmp << std::endl;
 

    std::cout << "test memset:" << std::endl;
    // void* memset( void* dest, int ch, std::size_t count );
    int a[4];
    using bits = std::bitset<sizeof(int) * CHAR_BIT>;
    std::memset(a, 0b1111'0000'0011, sizeof a);
    for (int ai : a)
        std::cout << bits(ai) << '\n';
 

    std::cout << "test memcpy:" << std::endl;
    std::cout << "\tarray_string_00 bfeore: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_01 bfeore: " << array_string_01 << std::endl;
    // void* memcpy( void* dest, const void* src, std::size_t count );
    std::memcpy(array_string_01, array_string_00, mem_size);      
    std::cout << "\tarray_string_00 after: " << array_string_00 << std::endl;
    std::cout << "\tarray_string_01 after: " << array_string_01 << std::endl;


    std::cout << "test memmove:" << std::endl;
    // void* memmove( void* dest, const void* src, std::size_t count );
    char str_memmove[] = "1234567890";
    std::cout << "\tbefore: " << str_memmove << '\n';
    std::memmove(str_memmove + 4, str_memmove + 3, 3); // copies from [4, 5, 6] to [5, 6, 7]
    std::cout << "\tafter: " << str_memmove << '\n';
 
    std::cout << "test strerror:" << std::endl;
    // strerror(int errnum);
 
}

Stringhe in stile C++

Le stringhe in stile C++ possono essere usate includendo l’header string, il quale mette a disposizione una serie di classi e metodi per la manipolazione di sequenze di caratteri.

#include <iostream>
#include <string>

int main(){
    std::string my_string = {"Ciao Mondo!"};
    std::cout << my_string << std::endl;

}

Classi

Tipo Definizione
std::string std::basic_string
std::wstring std::basic_string
std::u8string (dal C++20) std::basic_string
std::u16string (dal C++11) std::basic_string
std::u32string (dal C++11) std::basic_string

Funzioni

Operatori  
concatena 2 o più stringhe operator+
lessicograficamente compara due stringhe operator==
lessicograficamente compara due stringhe (removed in C++20) operator!=
lessicograficamente compara due stringhe (removed in C++20) operator<
lessicograficamente compara due stringhe (removed in C++20) operator>
lessicograficamente compara due stringhe (removed in C++20) operator<=
lessicograficamente compara due stringhe (removed in C++20) operator>=
lessicograficamente compara due stringhe (C++20) operator<=>
specilizza std::swap per le stringhe, inverte il contenuto di due stringhe swap
cancella tutti gli elementi erase
cancella tutti gli elementi che soddisfano criteri specifici erase_if


Input/output  
esegue input e output del flusso su stringhe operator«
esegue input e output del flusso su stringhe operator»
legge dati da I/O su stringhe getline


Conversioni Numeriche  
converte una stringa in un intero con segno (C++11) stoi
converte una stringa in un intero con segno (C++11) stol
converte una stringa in un intero con segno (C++11) stoll
converte una stringa in un intero senza segno (C++11) stoul
converte una stringa in un intero senza segno (C++11) stoull
converte una stringa in un numero in virgola mobile (C++11) stof
converte una stringa in un numero in virgola mobile (C++11) stod
converte una stringa in un numero in virgola mobile (C++11) stold
converte un valore intero o a virgola mobile in una stringa (C++11) to_string
converte un valore intero o a virgola mobile in una wstring (C++11) to_wstring


Accesso  
restituisce un iteratore all’inizio di un contenitore o di un array (C++11) begin
restituisce un iteratore all’inizio di un contenitore o di un array (C++14) cbegin
restituisce un iteratore alla fine di un contenitore o di un array (C++11) end
restituisce un iteratore alla fine di un contenitore o array (C++14) cend
restituisce un iteratore inverso all’inizio di un contenitore o array (C++14) rbegin
restituisce un iteratore inverso all’inizio di un contenitore o array (C++14) crbegin
restituisce un iteratore di fine inversa per un contenitore o un array (C++14) rend
restituisce un iteratore di fine inversa per un contenitore o un array (C++14) crend
restituisce la dimensione di un contenitore o di un array (C++17) size
restituisce la dimensione di un contenitore o di un array (C++20) ssize
controlla se il contenitore è vuoto (C++17) empty
ottiene il puntatore ai dati della matrice sottostante (C++17) data


Literals  
converts a character array literal to basic_string (C++14) operator””s
#include <iostream>
#include <string>
 
int main()
{
    using namespace std::literals;
 
    // creare una string da const char*
    std::string str1 = "hello";
 
    // creare una string usando un string literal
    auto str2 = "world"s;
 
    // Concatenare  stringhe
    std::string str3 = str1 + " " + str2;
 
    // Stampare una string
    std::cout << str3 << '\n';
 
    // trovare la posizione del primo spazio
    std::string::size_type pos = str3.find(" ");
    str1 = str3.substr(pos + 1); // estrarre la parte dopo lo spazio
    str2 = str3.substr(0, pos);  // estrarre la parte prima dello spazio
 
    std::cout << str1 << ' ' << str2 << '\n';
 
    // accedere ad lementi della stringa usando l'operatore []
    std::cout << str1[0] << '\n';
    str1[0] = 'W';
    std::cout << str1 << '\n';
}

Riferimenti