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

Wskaźniki i tablice na odwrót

Object Storage Arubacloud
0 głosów
153 wizyt
pytanie zadane 26 kwietnia 2017 w C i C++ przez benzulli Użytkownik (720 p.)

Otóż chcę zapisać string jakiś tam w następującej postaci (posłużmy się przykładem "ala ma kota"):

[img]http://i.imgur.com/b8pY7s1.png[/img]

        for(i = 0; i < k; i++)
        {
            for(j = 0; j < w+1; j++)
            {
                if(b = *dd++, b != ' ')
                    tab[j][i] = b;
                else if(b == ' ')
                {
                    break;
                }
            }
        }

Tym kodem tworzę pierwszy rodzaj zapisu, czyli jakby przepisuję pionowo do tablicy. Wszystko jest niby ok, tylko mam jedno pytanie do tego kodu, gdyż jeśli dam inny string i jeśli najdłuższy wyraz pojawi się gdzieś w środku (wyraz o maksymalnym rozmiarze liczby wierszów w tablicy), gdy nie zostanie spełniony pierwszy warunek, czyli wykonuje się else if i wtedy break, to break tak jakby zastosowuje się do pierwszej pętli i dalej do tablicy przypisywane są znaki, ale jakby o jedną kolumnę za daleko. Problem się rozwiązuje, gdy zwiększam rozmiar wykonywania się pętli środkowej, wtedy break jakby nie ingeruje w zewnętrzną pętle (1) - pierwszy problem.

 

        while(*dd++);
        *dd--;
        for(i = k-1; i >= 0; i--)
        {
            for(j = w; j >= 0; j--)
            {
                if(b = *dd--, b != ' ')
                    tab[j][i] = b;
                else if(b == ' ')
                {
                   break;
                }
            }
        }

Tym kodem zaś rozwiązuję drugi rodzaj zapisu, czyli "opuszczone" słowa na sam dół tablicy. Wskaźnik ustawiony na sam koniec, gdyż postanowiłem, że od końca będzie najlepiej to zrobić i najszybciej. Zatem pierwszy problem na jaki się napotkałem to, że gdy ustawię 

j = w-1;

czyli tak, jak powinno być poprawnie (no bo zaczynam od prawego, dolnego rogu) to wtedy jakby zaczyna mi od wiersza wyżej i muszę ustawić

j = w;

żeby zaczęło wpisywać elementy poprawnie (??). Kolejna sprawa jest taka, że gdy jest najdłuższe słowo (które ma taką samą długość jak ilość wierszy), to przy ostatnim wykonaniu wewnętrznego fora, następny wyraz "przesuwa się" o kolumnę za daleko, czyli jakby znowu break dotyczył tego zewnętrznego fora, zamiast wewnętrznego i tutaj już się nie da tego rozwiązać jak wcześniej, gdyż po prostu nie ma indeksów mniejszych od 0. 

 

#include <stdio.h>
#include <string.h>
#define MAX_LINE 256

int main()
{
    int licz_slowa(char *), maks_liter(char *), lspk(char *, int), ns, option = 0, i, j, w, k;
    char s[MAX_LINE], *dd, b;
    dd = gets(s);
    printf("ile slow: %d\nnajdlusze slowo: ", licz_slowa(dd));
    printf("%d\n", maks_liter(dd));
    w = maks_liter(dd); // ilosc wierszy, najdluzsze slowo
    k = licz_slowa(dd); // liczba slow, ilosc kolumn
    printf("wiersze: %d \nkolumny: %d\n", w, k);
    char tab[w][k];
    for(i = 0; i < w; i++)
    {
        for(j = 0; j < k; j++)
            tab[i][j] = ' ';
    }
    if(option)
    {
        for(i = 0; i < k; i++)
        {
            for(j = 0; j < w+1; j++)
            {
                if(b = *dd++, b != ' ')
                    tab[j][i] = b;
                else if(b == ' ')
                {
                    break;
                }
            }
        }
    }
    else
    {
        while(*dd++);
        *dd--;
        for(i = k-1; i >= 0; i--)
        {
            for(j = w; j >= 0; j--)
            {
                if(b = *dd--, b != ' ')
                    tab[j][i] = b;
                else if(b == ' ')
                {
                   break;
                }
            }
        }
    }
    for(i = 0; i < w; i++)
    {
        for(j = 0; j < k; j++)
            printf("%c   ", tab[i][j]);
        printf("\n");
    }
   // printf("\n\n\n %d", lspk(dd, 0));
}

int licz_slowa(char *tab) // wskaznik na tablice i na najdluzsze slowo
{
    char p, b = ' ';
    int s = 0; // s = suma slow, n = najdlusze slowo, temp = najdluzsze slowo temporary
    while(p = b, b = *tab++)
        if(b != ' ' && p == ' ')
            s++;
    return s;
}

int maks_liter(char *tab)
{
    char b;
    int max = 0, temp = 0;
    while(b = *tab++)
    {
        if(b == ' ')
        {
            temp = 0;
        }
        else
            temp++;
        if(temp > max) max = temp;
    }
    return max;
}

/*int lspk(char *tab, int nr) // licz slowa po kolei
{
    char b;
    int k = 0, bk = 0;
    while(b = *tab++)
    {
        if(nr == bk)
        {
            while(*tab++ != ' ')
                k++;
        }
        if(b == ' ') bk++;
    }
    return k;
}*/

Wstawiam cały kod, jakby ktoś się chciał pobawić, jak jest if option, to pierwsza instrukcja jest do sytuacji pierwszej ze screena, a druga analogicznie (z tym, że druga nie do końca działa poprawnie, bo zjada litery przy przechodzeniu do kolejnych kolumn, ten brejk jest jakąś zakałą).

komentarz 28 kwietnia 2017 przez benzulli Użytkownik (720 p.)

Jeśli kogoś to interesuje, to udało mi się "naprawić" program, choć nadal nie wiem, dlaczego muszę cofać pętlę wewnętrzną przy wyrazie, który ma maksymalny rozmiar tablicy.

 

#include <stdio.h>
#include <string.h>
#define MAX_LINE 256

int main()
{
    int licz_slowa(char *), maks_liter(char *), lspk(char *, int), ns, option = 0, i, j, w, k;
    char s[MAX_LINE], *dd, b;
    dd = gets(s);
    printf("ile slow: %d\nnajdlusze slowo: ", licz_slowa(dd));
    printf("%d\n", maks_liter(dd));
    w = maks_liter(dd); // ilosc wierszy, najdluzsze slowo
    k = licz_slowa(dd); // liczba slow, ilosc kolumn
    printf("wiersze: %d \nkolumny: %d\n", w, k);
    char tab[w][k];
    for(i = 0; i < w; i++)
    {
        for(j = 0; j < k; j++)
            tab[i][j] = ' ';
    }
    if(option)
    {
        for(i = 0; i < k; i++)
        {
            if(j==w) i--;
            for(j = 0; j < w; j++)
            {
                b = *dd++;
                if(b != ' ' && b != '\0')
                    tab[j][i] = b;
                else if(b == ' ' || b == '\0')
                {
                    break;
                }
            }
        }
    }
    else
    {
        while(*dd++);
        *dd--;
        *dd--;
        for(i = k-1; i >= 0; i--)
        {
            if(j==-1) i++;
            for(j = w-1; j >= 0; j--)
            {
                b = *dd--;
                if(b != ' ')
                    tab[j][i] = b;
                else if(b == ' ' || b == '\0')
                {
                    break;
                }
            }
        }
    }
    for(i = 0; i < w; i++)
    {
        for(j = 0; j < k; j++)
            printf("%c   ", tab[i][j]);
        printf("\n");
    }
    // printf("\n\n\n %d", lspk(dd, 0));
}

int licz_slowa(char *tab) // wskaznik na tablice i na najdluzsze slowo
{
    char p, b = ' ';
    int s = 0; // s = suma slow, n = najdlusze slowo, temp = najdluzsze slowo temporary
    while(p = b, b = *tab++)
        if(b != ' ' && p == ' ')
            s++;
    return s;
}

int maks_liter(char *tab)
{
    char b;
    int max = 0, temp = 0;
    while(b = *tab++)
    {
        if(b == ' ')
        {
            temp = 0;
        }
        else
            temp++;
        if(temp > max) max = temp;
    }
    return max;
}

/*int lspk(char *tab, int nr) // licz slowa po kolei
{
    char b;
    int k = 0, bk = 0;
    while(b = *tab++)
    {
        if(nr == bk)
        {
            while(*tab++ != ' ')
                k++;
        }
        if(b == ' ') bk++;
    }
    return k;
}*/

 

1 odpowiedź

+1 głos
odpowiedź 26 kwietnia 2017 przez Wiciorny Ekspert (269,770 p.)
Break przerwie iteracje pentli wewnętrznej, nie zewnętrznej.

Strasznie nieczytelny ten kod,  zajme się nim jutro rano z ciekawości to może coś doradzę głębiej

Podobne pytania

0 głosów
1 odpowiedź 208 wizyt
pytanie zadane 1 grudnia 2022 w C i C++ przez Pysa6 Nowicjusz (220 p.)
0 głosów
1 odpowiedź 256 wizyt
pytanie zadane 7 września 2022 w C i C++ przez benny13 Obywatel (1,150 p.)
0 głosów
0 odpowiedzi 426 wizyt

92,567 zapytań

141,420 odpowiedzi

319,615 komentarzy

61,952 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!

...