• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Double "double" pointer? Wskaźniki i sortowanie zdań oraz samych w nim słów. :)

Object Storage Arubacloud
0 głosów
239 wizyt
pytanie zadane 18 maja 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)

Cześć :)

Wykonuję obecnie takie zdanie:

Napisz program, który pobierze od użytkownika tekst, podzieli go na zdania i wyświetli posortowane rosnąco ze względu na liczby słów w tych zdaniach. Zdania mają być wyświetlone w oddzielnych liniach, ze słowami posortowanymi alfabetycznie, ze względu na wynik funkcji strcmp.

Przykład:

Enter text: "In theory, theory and practice are the same. In practice, they're not." - Yoggi Berra⏎
In not practice re they⏎
In and are practice same the theory theory⏎ 
W tym celu przygotuj następujące funkcje:

int split_sentences(const char *text, char ****output);
int sort_sentences(char ***output);
void destroy(char ***words);
int split_sentences(const char *text, char ****output);
Funkcja dzieli tekst text na zdania. Zdanie kończy się kropką. Ponadto każde zdanie dzieli na wyrazy. Wyraz to ciąg następujących po sobie liter.

Przykłady:

dwa zdania (Ala oraz Ma): Ala .Ma. Kota
jedno zdanie (kota): kota.
brak zdań: ala ma kota
dwa puste zdania: ..
Koniec tablic zdań oraz wyrazów funkcja ma oznaczyć wartością NULL. Poszczególne wyrazy, jako że są tekstami, kończą się terminatorem '\\x0'

Funkcja może zaalokować dokładnie tyle pamięci, ile będzie potrzebne na przechowanie całej tablicy. Wynik działania funkcji split_sentences ma zostać napisany pod wskaźnik *output. Jeżeli funkcja ma zakończyć się porażką, to powinna ustawić NULL podwskaźnikiem *output* i zwrócić niezerowy kod błędu.

Wartość zwracana:

1 - w przypadku przekazania do funkcji błędnych danych,
2 - w przypadku braku zdań w tekście text,
3 - w przypadku braku pamięci,
0 - w przypadku sukcesu (*output zawiera poprawny wskaźnik).
Interpretacja parametru char ****output:

Poziom znaku - typ char reprezentuje pojedynczy znak.
Poziom słowa - typ wskaźnikowy char* reprezentuje wskaźnik na znak, który w tym przypadku należy interpretować jako wskaźnik na słowo (wskaźnik na pierwszy znak słowa, słowo jest tekstem w języku C i kończy się terminatorem \x0).
Poziom zdania - typ wskaźnikowy char** jest wskaźnikiem na pamięć przechowującą wskaźnik na słowo. W tym przypadku należy interpretować go jako wskaźnik na pamięć przechowującą sekwencję wielu wskaźników na słowa; sam wskaźnik char** wskazuje tylko na pierwsze słowo (wskaźnik do niego). Sekwencja musi kończyć się terminatorem NULL. Zatem zdanie posiadające 5 słów będzie reprezentowane przez sekwencję 6 elementów (ostatni to NULL).
Poziom tekstu - typ wskaźnikowy char***, analogicznie do poprzedniego przykładu, wskazuje na sekwencję wskaźników na zadania. Zatem można go interpretować jako wskaźnik na cały treść/dokument (czyli zbiór zdań). Sekwencja kończy się terminatorem NULL.
Poziom zmiennej przechowującej wskaźnik na treść - typ wskaźnikowy char*** ponownie opisuje wskaźnik do pamięci przechowującej wskaźnik, itd. W tym przypadku należy go interpretować jako adres zmiennej typu char*** w której umieszczony ma być adres pierwszego zdania tekstu wejściowego.
Zatem jeśli przyjmiemy, że zmienna char**** p zawiera poprawny wskaźnik z poprawnie przydzielonymi pamięciami, to odpowiednio:

*p - Adres całej treści podzielonej na zdania i słowa. Typ tego wyrażenia to char***
*(*p + 1) - Adres drugiego zdania w tekście *p (pierwsze ma indeks 0). Typ tego wyrażenia to char**
*(*(*p + 2) + 4) - Piąte słowo z trzeciego tekstu. Typ tego wyrażenia to char*.
*(*(*(*p + 1) + 6) + 8) - Dziewiąty znak z siódmego słowa znajdującego się w drugim wierszu. Typ tego wyrażenia to char.
Natomiast wyrażenie *(p + 1) jest niepoprawne, ponieważ p jest adresem jednej zmiennej (jednego elementu wskaźnikowego). Za tym elementem nie ma nic, co dało by się zinterpretować w kontekście treści/zdań/słów.
int sort_sentences(char ***output);
Funkcja sortuje zdania w output rosnąco pod kątem liczby wyrazów w nich występujących. Ponadto w każdym zdaniu wyrazy należy posortować alfabetycznie od A do Z, przy czym duże litery mają wyższy priorytet, pomimo mniejszej wartości ich kodów tabeli ASCII. Sortowanie należy realizować w miejscu.

Koniec słów w tablicy (zdaniu) jest oznaczony wartością NULL. Koniec zdań w tablicy (output) jest oznaczony wartością NULL.

Wartość zwracana:

1 - w przypadku błędnych danych wejściowych lub
0 w przypadku powodzenia.
void destroy(char ***words);
Funkcja zwalnia pamięć przydzieloną zarówno na tablicę words, jak i poszczególne wyrazy.

Napisz program, który pobierze od użytkownika tekst (nie więcej niż 999 znaków), podzieli go na zdania, każde zdanie podzieli na wyrazy a następnie posortuje zdania rosnąco pod względem liczby wyrazów, a wyrazy w poszczególnych zdaniach alfabetycznie.

Program ma wyświetlić, w oddzielnej linii dla każdego zdania, wyrazy posortowane alfabetycznie począwszy od zdania z najmniejszą liczbą wyrazów.

W przypadku, kiedy nie uda się przydzielić pamięci program powinien wyświetlić komunikat Failed to allocate memory i niezwłocznie zakończyć działanie z kodem błędu 8,
W przypadku kiedy nie będzie żadnych zdań w tekście podanym przez użytkownika program powinien wyświetlić komunikat Nothing to show.
Jeżeli w którymś ze zdań nie będzie wyrazów, program w jego miejsce powinien wyświetlić komunikat Nothing to show i kontynuować.

Przykładowa interakcja z programem -- skrajny przypadek:

Enter text:                          ,              .      ,                    ,                .                  ,                                .                                                          . -    .Technology is teaching us to be human again.-Simon Mainwaring⏎
Nothing to show⏎
Nothing to show⏎
Nothing to show⏎
Nothing to show⏎
Nothing to show⏎
Technology again be human is teaching to us⏎

Uwaga

  • W programie nie wolno korzystać z operatora [].

 

 

A oto i mój kod:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>


int split_sentences(const char *text, char ****output);
int sort_sentences(char ***output);
void destroy(char ***words);
void print_output(char ***output);

int main()
{
    printf("Enter text: ");
    char * pointer;
    pointer = (char *) malloc (sizeof(char) * 2500 );
    if( pointer == NULL )
    {
        printf("Failed to allocate memory");
        return 8;
    }
    scanf(" %2500[^\n]",pointer);
    *(pointer + 999) = '\0';
    char *** output;
    int result = 0;
    result = split_sentences( (const char *) pointer, &output);
    if( result == 0 )
    {

    }
    if( result == 2 )
    {
        printf("Nothing to show");
        free(pointer);
        return 0;
    }
    print_output(output);

}

void print_output(char ***output)
{
    int i = 0, j = 0;
    while( *( output + i) != NULL  )
    {
        j = 0;
        while( *(*(output + i) + j) != NULL   )
        {
            printf("%s ",*(*(output + i) + j));
            j++;
        }
        if( j == 0 )
        {
            printf("Nothing to show");
        }
        printf("\n");
        i++;
    }
}

void destroy(char ***words)
{
    if( words == NULL )
    {

    }
    else
    {
        int i = 0, j = 0;
        while( *(words + i) != NULL  )
        {
            while(  *( *(words + i) + j) != NULL  )
            {
                free(*( *(words + i) + j));
                j++;
            }
            free(*(words + i));
            i++;
        }
        free(words);
    }

}

int split_sentences(const char *text, char ****output)
{
    if( text == NULL || output == NULL )
    {
        return 1;
    }
    int sentences = 0;
    int i = strlen(text) - 1; // wskazuje na terminatra
    while( *(text + i) == ' '  )
    {
        i--;
    }
    int ending = i + 1;
    i = 0;
    while( *(text + i) == ' ' )
    {
        i++;
    }
    int start = i;
    while( *(text + i) != '\0' )
    {
        if( *(text + i) == '.' )
        {
            sentences++;
        }
        i++;
    }
    if( sentences == 0 )
    {
        return 2;
    }
    *output = (char ***) malloc(sizeof(char **) * (sentences + 1) );
    if( *output == NULL )
    {
        return 3;
    }
    *( (*output) +  sentences) = NULL;
    i = 0;
    int j = 0;
    int itr = start;
    while( *(text + itr ) != '\0' && itr < ending  )
    {
       if( isalpha( *(text + itr ) ) != 0    )
       {
           while( isalpha( *(text + itr)  ) != 0   )
           {
               itr++;
           }
           j++;

       }
       if( *(text + itr) == '.'  )
       {
            *( (*output) + i) = (char **) malloc(sizeof(char *) * (j + 1) );
            if(  *( (*output) + i ) == NULL  ) // błąd alokacji wyrazów dla poszczególnych zdań
            {
                int get_out = 0;
                for(get_out = 0; get_out < i; get_out++)
                {
                    free(*( (*output) + get_out ) );
                }
                free(*output);
                return 3;
            }
            *(*( (*output) + i ) + j) = NULL;
            j = 0;
            i++;
       }
       if(  isalpha( *(text + itr ) ) == 0 )
       {
           itr++;
       }
    }
    itr = start;
    i = 0;
    j = 0;
    int k = 0;
    while( *(text + itr) != '\0' && itr < ending ) // alokacja dla liter dla wyrazów
    {
        if(  isalpha(*(text + itr)) != 0  )
        {
            k = 0;
            while( isalpha(*(text + itr)) != 0 )
            {
                itr++;
                k++;
            }
            *(*( (*output) + i ) + j) = (char *) malloc (sizeof(char) * (k + 1) );
            if( *(*( (*output) + i ) + j) == NULL )
            {
                int get_out_sentences = 0;
                int get_out_words = 0;
                for(get_out_sentences = 0; get_out_sentences <= i; i++ )
                {
                    for(get_out_words = 0; get_out_words < j; get_out_words++)
                    {
                        free( *(*( (*output) +  get_out_sentences ) +   get_out_words )  );
                    }
                    free(  *( (*output) + get_out_sentences )  );
                }
                free( *output );
                return 3;
            }
            j++;
        }
        if( *(text + itr) == '.' )
        {
            j = 0;
            k = 0;
            i++;
        }
        if( isalpha(*(text + itr)) == 0 )
        {
            itr++;
        }
    }
    itr = start;
    i = 0;
    j = 0;
    k = 0;
    while( *(text + itr) != '\0' && itr < ending )
    {
        if( isalpha( *(text + itr) ) != 0  )
        {
            k = 0;
            while( isalpha( *(text + itr) ) != 0 )
            {
                *(*(*( (*output) + i ) + j) + k) = *(text + itr);
                k++;
                itr++;
            }
            *(*(*( (*output) + i ) + j) + k) = '\0';
            j++;
        }
        if( *(text + itr) == '.'  )
        {

            j = 0;
            k = 0;
            i++;
        }
        if( isalpha( *(text + itr) ) == 0 )
        {
            itr++;
        }
    }
    return 0;
}
int sort_sentences(char ***output)
{
    if( output == NULL )
    {
        return 1;
    }
    int i = 0, j = 0;
    while( *(output + i) != NULL )
    {
        while( *(*(output + i) + j + 1) != NULL   )
        {
            if( strcmp( *(*(output + i) + j ) , *(*(output + i) + j + 1)  ) > 0 ) //women większe od A, B  większe od A itd. itd.
           {
               char *swapp = *(*(output + i) + j );
               *(*(output + i) + j ) = *(*(output + i) + j + 1);
               *(*(output + i) + j + 1) = swapp;
           }
            j++;
        }
        i++;
    }

    return 0;
}

Dla poniższych danych efekt bez uwzględnienia sortowania jest następujący:

Enter text: Ala ma kota. Serio. Naprawde. Sto procent legit. No scam.
Ala ma kota
Serio
Naprawde
Sto procent legit
No scam

Process returned 0 (0x0)   execution time : 11.138 s
Press any key to continue.

Z czym na tą chwilę mam problem:

1) Nie wiem czemu, ale gdy po ostatnim zdaniu coś piszę (coś co nie powinno być już brane pod uwagę, bo już wszystkie zdania są uwzględnione) dzieje mi się takie coś:

Enter text:      .            .     Serio      .     Ala

Process returned -1073741819 (0xC0000005)   execution time : 10.440 s
Press any key to continue.

albo w ten sposób:

Enter text: Ala ma kota.    a

Process returned -1073741819 (0xC0000005)   execution time : 6.326 s
Press any key to continue.

Podpowiecie mi czego nie zrobiłem w moim kodzie dla problemu w tym podpunkcie?  :(

2) Funkcja sort jest nie dokończona. Na tę chwilę mam tylko sortowanie wyrazów w zdaniu (swoją drogą możecie się wypowiedzieć, czy wszystko na ten czas zrobiłem poprawnie). Jak mogę przeprowadzić sortowanie zdań? Czuję, że pewnie rozwiązanie jest proste i powinno mi stać przed oczami, ale jest już późna godzina i chyba nie zbyt już jasno myślę.   :(

Z góry dziękuję za wszelkie odpowiedzi.   :)

komentarz 18 maja 2020 przez j23 Mędrzec (194,920 p.)
Funkcja, która ma 147 linii, to nic dobrego. Podziel ją na mniejsze funkcje.
komentarz 18 maja 2020 przez Hubertius Bywalec (2,970 p.)

Okej, mniej więcej tak to podzieliłem:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>


int split_sentences(const char *text, char ****output);
int check_for_errors(const char *text, char ****output, char * start, char *ending, char * sentences);
int allocation_for_words(const char * text,char ****output,char * start, char * ending);
int allocation_for_letters(char *text,char ****output,char * start,char * ending);
int writing_from_txt_to_out(char *text,char ****output,char * start,char * ending);


int sort_sentences(char ***output);
void destroy(char ***words);

void print_output(char ***output);


int main()
{
    printf("Enter text: ");
    char * pointer;
    pointer = (char *) malloc (sizeof(char) * 2500 );
    if( pointer == NULL )
    {
        printf("Failed to allocate memory");
        return 8;
    }
    scanf(" %2500[^\n]",pointer);
    *(pointer + 999) = '\0';
    char *** output;
    int result = 0;
    result = split_sentences( (const char *) pointer, &output);
    if( result == 0 )
    {

    }
    if( result == 2 )
    {
        printf("Nothing to show");
        free(pointer);
        return 0;
    }
    print_output(output);

}

void print_output(char ***output)
{
    int i = 0, j = 0;
    while( *( output + i) != NULL  )
    {
        j = 0;
        while( *(*(output + i) + j) != NULL   )
        {
            printf("%s ",*(*(output + i) + j));
            j++;
        }
        if( j == 0 )
        {
            printf("Nothing to show");
        }
        printf("\n");
        i++;
    }
}

void destroy(char ***words)
{
    if( words == NULL )
    {

    }
    else
    {
        int i = 0, j = 0;
        while( *(words + i) != NULL  )
        {
            while(  *( *(words + i) + j) != NULL  )
            {
                free(*( *(words + i) + j));
                j++;
            }
            free(*(words + i));
            i++;
        }
        free(words);
    }

}

int split_sentences(const char *text, char ****output)
{
    int sentences = 0;
    int start = 0;
    int ending = 0;
    int result;
    result = check_for_errors(text,output,&start,&ending,&sentences);
    if( result == 1 )
    {
        return 1;
    }
    if( result == 2 )
    {
        return 2;
    }
    *output = (char ***) malloc(sizeof(char **) * (sentences + 1) );
    if( *output == NULL )
    {
        return 3;
    }
    *( (*output) +  sentences) = NULL;

    result = allocation_for_words(text,output,&start,&ending);
    if( result == 3 )
    {
        return 3;
    }
    result = allocation_for_letters(text,output,&start,&ending);
    if( result == 3 )
    {
        return 3;
    }
    writing_from_txt_to_out(text,output,&start,&ending);
    return 0;
}


int check_for_errors(const char *text, char ****output, char * start, char * ending, char * sentences)
{
    if( text == NULL || output == NULL )
    {
        return 1;
    }
    *sentences = 0;
    int i = strlen(text) - 1; // wskazuje na terminatora
    while( *(text + i) == ' '  )
    {
        i--;
    }
    *ending = i + 1;
    i = 0;
    while( *(text + i) == ' ' )
    {
        i++;
    }
    *start = i;
    while( *(text + i) != '\0' )
    {
        if( *(text + i) == '.' )
        {
            *sentences = *sentences + 1;
        }
        i++;
    }
    if( *sentences == 0 )
    {
        return 2;
    }
    return 0;
}
int allocation_for_words(const char * text,char ****output,char * start, char * ending)
{
    int i = 0;
    int j = 0;
    int itr = *start;
    while( *(text + itr ) != '\0' && itr < *ending  )
    {
       if( isalpha( *(text + itr ) ) != 0    )
       {
           while( isalpha( *(text + itr)  ) != 0   )
           {
               itr++;
           }
           j++;
       }
       if( *(text + itr) == '.'  )
       {
            *( (*output) + i) = (char **) malloc(sizeof(char *) * (j + 1) );
            if(  *( (*output) + i ) == NULL  ) // błąd alokacji wyrazów dla poszczególnych zdań
            {
                int get_out = 0;
                for(get_out = 0; get_out < i; get_out++)
                {
                    free(*( (*output) + get_out ) );
                }
                free(*output);
                return 3;
            }
            *(*( (*output) + i ) + j) = NULL;
            j = 0;
            i++;
       }
       if(  isalpha( *(text + itr ) ) == 0 )
       {
           itr++;
       }
    }
    return 0;
}

int allocation_for_letters(char *text,char ****output,char * start,char * ending)
{
    int itr = *start;
    int i = 0;
    int j = 0;
    int k = 0;
    while( *(text + itr) != '\0' && itr < *ending ) // alokacja dla liter dla wyrazów
    {
        if(  isalpha(*(text + itr)) != 0  )
        {
            k = 0;
            while( isalpha(*(text + itr)) != 0 )
            {
                itr++;
                k++;
            }
            *(*( (*output) + i ) + j) = (char *) malloc (sizeof(char) * (k + 1) );
            if( *(*( (*output) + i ) + j) == NULL )
            {
                int get_out_sentences = 0;
                int get_out_words = 0;
                for(get_out_sentences = 0; get_out_sentences <= i; i++ )
                {
                    for(get_out_words = 0; get_out_words < j; get_out_words++)
                    {
                        free( *(*( (*output) +  get_out_sentences ) +   get_out_words )  );
                    }
                    free(  *( (*output) + get_out_sentences )  );
                }
                free( *output );
                return 3;
            }
            j++;
        }
        if( *(text + itr) == '.' )
        {
            j = 0;
            k = 0;
            i++;
        }
        if( isalpha(*(text + itr)) == 0 )
        {
            itr++;
        }
    }
    return 0;
}

int writing_from_txt_to_out(char *text,char ****output,char * start,char * ending)
{
    int itr = *start;
    int i = 0;
    int j = 0;
    int k = 0;
    while( *(text + itr) != '\0' && itr < ending )
    {
        if( isalpha( *(text + itr) ) != 0  )
        {
            k = 0;
            while( isalpha( *(text + itr) ) != 0 )
            {
                *(*(*( (*output) + i ) + j) + k) = *(text + itr);
                k++;
                itr++;
            }
            *(*(*( (*output) + i ) + j) + k) = '\0';
            j++;
        }
        if( *(text + itr) == '.'  )
        {
            j = 0;
            k = 0;
            i++;
        }
        if( isalpha( *(text + itr) ) == 0 )
        {
            itr++;
        }
    }
    return 0;
}

int sort_sentences(char ***output)
{
    if( output == NULL )
    {
        return 1;
    }
    int i = 0, j = 0;
    while( *(output + i) != NULL )
    {
        while( *(*(output + i) + j + 1) != NULL   )
        {
            if( strcmp( *(*(output + i) + j ) , *(*(output + i) + j + 1)  ) > 0 ) //women większe od A, B  większe od A itd. itd.
           {
               char *swapp = *(*(output + i) + j );
               *(*(output + i) + j ) = *(*(output + i) + j + 1);
               *(*(output + i) + j + 1) = swapp;
           }
            j++;
        }
        i++;
    }

    return 0;
}
komentarz 18 maja 2020 przez j23 Mędrzec (194,920 p.)
edycja 19 maja 2020 przez j23

Od razu lepiej, acz wydaje mi się to przekomplikowane.

Tu masz przykład bardziej "skondensowany":

int split_words(const char * begin, const char * end, char ***output)
{
    char ** words = NULL;
    size_t n_words = 0;
    
    while(begin != end) {
        while(begin != end && isspace(*begin)) ++begin;
        const char * p = begin;
        while(p != end && !isspace(*p)) ++p;
        words = realloc(words, sizeof(char*) * (n_words + 2));
        if(!words) return 3;
        size_t len = p - begin;
        char* word = malloc(len + 1);
        word[len] = 0;
        if(!word) return 3;
        words[n_words++] = strncpy(word, begin, len);
        words[n_words] = NULL; 
        begin = p;
    }
    
    *output = words;
    return 0;
}

int split_sequences(const char * text, char ****output)
{
    char ***seqs = NULL;
    size_t n_seqs = 0;
    char **words;
    
    if (!text || !output) return 1;

    while (*text != 0) {
        const char *end = text;
        
        while(*end && *end != '.') ++end;
        if(*end == 0) break;
        int res = split_words(text, end, &words);
        if(res != 0) return res;
        seqs = realloc(seqs, sizeof(char**) * (n_seqs + 2));
        if(!seqs) return 3;
        seqs[n_seqs++] = words;
        seqs[n_seqs] = NULL;
        text = end;
        if(*text == '.') ++text;
    }
    
    *output = seqs;
    return seqs ? 0 : 2;
}



int main()
{
    const char* text = "ala ma kota. a kot ma ale.  ";
    char*** seqs;
    
    split_sequences(text, &seqs);
    
    for (size_t i = 0; seqs[i]; ++i) {
        for (size_t j = 0; seqs[i][j]; ++j)
            printf("%s\n", seqs[i][j]);
        printf("\n");
    }
}

Wystarczy teraz zaimplementować sortowanie ;)

komentarz 20 maja 2020 przez Hubertius Bywalec (2,970 p.)
Przez te ostatnie dwa dni walczyłem ostro z testami dla funkcji split_sentence. Teraz, gdy już wszystko przeszło mogę się skupić na sort. A więc co robię nie tak dla przedstawionego przeze mnie wyżej sortowania wyrazów w zdaniach. I jak mogę posortować same zdania ze względu na ilość wyrazów?
komentarz 20 maja 2020 przez j23 Mędrzec (194,920 p.)
edycja 20 maja 2020 przez j23

A więc co robię nie tak dla przedstawionego przeze mnie wyżej sortowania wyrazów w zdaniach.

Porównujesz łańcuchy znakowe zamiast ilości wyrazów. Następna rzecz to indeks j - nie zerujesz go.

 

Tak to jakoś widzę:

int sort_sentences(char*** output)
{
    if (output == NULL) {
        return 1;
    }

	char*** p = output;

	while (p) ++p;
	
	size_t n = p - output;

	for (size_t i = 0; i < n; ++i) {
		for (size_t j = 1; j < n - i; ++j) {
			if (get_len(*(output + j - 1)) > get_len(*(output + j))) {
                char** words = *(output + j);
                *(output + j) = *(output + j - 1);
                *(output + j - 1) = words;
			}
		}
	}
	
    return 0;
}

Napisz sobie funkcję get_len, która zwraca ilość wyrazów w tablicy wyrazów.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 504 wizyt
pytanie zadane 21 kwietnia 2020 w C i C++ przez Hubertius Bywalec (2,970 p.)
0 głosów
2 odpowiedzi 455 wizyt
0 głosów
1 odpowiedź 128 wizyt
pytanie zadane 21 maja 2020 w C i C++ przez Marcin4 Użytkownik (570 p.)

92,551 zapytań

141,399 odpowiedzi

319,531 komentarzy

61,937 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...