Usuniecie czesci string i przepisanie do innej zmiennej

Odpowiedz Nowy wątek
2017-04-21 08:25
0

Witam. W swoim programie dostaje na przykład komendę od użytkownika: wypisz >> plik. Moim zadaniem jest zapisanie stringa do wystąpienia znaków >> do jednej zmiennej, a to co jest po >> ma być zapisane do 2 zmiennej. 1 część działa dobrze ale 2 już nie koniecznie. Prosiłbym bardziej doświadczonego programistę ode mnie o pomocne wskazówki. Dziękuję za odpowiedz.

void parse(char *linia, char **argv, char *argv2)
{
    while (*linia != '\0')
    {
            while (*linia == ' ' || *linia == '\t' || *linia == '\n')
            *linia++ = '\0';
            if(*linia=='>' && *(linia+1)=='>' )
            {
                    *linia++;
                    *linia++;
                    *linia++;
                    while(*linia!='\0')
                    {
                        argv2 = linia;
                        *linia++;
                        *argv2++;
                    }   
                    *argv2 = '\0';
                    break;
            }
            *argv++ = linia;
            while (*linia != '\0' && *linia != ' ' &&  *linia != '\t' && *linia != '\n')
                linia++;
    }
    *argv = '\0';
}
edytowany 2x, ostatnio: ByQQ, 2017-04-21 08:28

Pozostało 580 znaków

2017-04-21 09:01
0

Ale musisz to robić w tak dziwny i nieczytelny sposób czy to taki prywatny fetysz? o_O Serio za coś takiego:

                    *linia++;
                    *linia++;
                    *linia++;

powinni łamać kołem...


Na PW przyjmuje tylko (ciekawe!) zlecenia. Masz problem? Pisz na forum, nie do mnie.

Pozostało 580 znaków

2017-04-21 11:02
0

Nie lepiej pobrać całą linię od użytkownika, a później lecieć literka po literce wrzucać to do realokowanej tablicy, jeżeli wystąpi << to przerwać i znowu? Szczerze nic nie rozumiem z tego kodu tym bardziej

                    *linia++;
                    *linia++;
                    *linia++;

Pozostało 580 znaków

2017-04-21 11:29
0
wyebani napisał(a):

Nie lepiej pobrać całą linię od użytkownika, a później lecieć literka po literce wrzucać to do realokowanej tablicy, jeżeli wystąpi << to przerwać i znowu? Szczerze nic nie rozumiem z tego kodu tym bardziej

                    *linia++;
                    *linia++;
                    *linia++;

Bo to nie ma sensu. Dereferencja nie jest potrzebna bo i tak do niczego nie przepisuje jej wyniku, A inkrementacja ma pierwszeńtwo przed dereferencją, tj inkrementaja wykona się na tym co wskazuje.

Wytłumacz jeszcze czemu argv i argv2 mają różne typy?

edytowany 2x, ostatnio: nalik, 2017-04-21 11:36

Pozostało 580 znaków

2017-04-21 11:34
0

W jakiś sposób muszę ominąć znak >> dlatego stosuje *linia++. Podając np. wykonaj >> plik, "plik" ma być zapisany do argv2.
Zmodyfikowałem kod:

char *parse(char *linia, char **argv)
{
    char *argv2;
    while (*linia != '\0')
    {
        printf("[%s]", linia);
        while (*linia == ' ' || *linia == '\t' || *linia == '\n')
            *linia++ = '\0';
        if(*linia=='>' && *(linia+1)=='>' )
        {
            linia = linia+3;
            argv2 = linia;
            break;
        }
        *argv++ = linia;
        while (*linia != '\0' && *linia != ' ' &&  *linia != '\t' && *linia != '\n'){
            linia++;
        }
    }
    *argv = '\0';
    return argv2;
}

i w main:

gets(komenda);
    strcmp(argv2,parse(komenda,argv));

Niestety to rozwiązanie dalej nie działa. Pod argv2 jest przypisane null

edytowany 4x, ostatnio: ByQQ, 2017-04-21 11:44

Pozostało 580 znaków

2017-04-21 11:38
1
ByQQ napisał(a):

W jakiś sposób muszę ominąć znak >> dlatego stosuje *linia++. Podając np. wykonaj >> plik, "plik" ma być zapisany do argv2.

Mistrzu wystarczy linia++; linia++; a najlepiej linia += 2 (tak, dwa razy, nie trzy!). To jest prosta inkrementacja wskaźnika. Nie ma potrzeby robić dereferencji bo i tak tego nie wykorzystasz. Kompilator sobie z tym poradzi i usunie martwy kod, który generujesz, ale to wygląda źle.

Do tego pierwszy while wykona się tylko do instrukcji break.

edytowany 2x, ostatnio: nalik, 2017-04-21 11:47
czy uważasz że zmiana na linia = linia+2; rozwiąże problem? - ByQQ 2017-04-21 11:47
Jeden z wielu. - nalik 2017-04-21 11:48
no dobrze to już poprawiłem. Problem jest nadal że już w main jako argv2 nie pokazuj mi tego "plik" mimo że zmienna argv2 w parse ma taką wartość - ByQQ 2017-04-21 11:50
Musisz skopiować zawartość a nie podmienić lokalną kopię wskaźnika. - nalik 2017-04-21 11:53
Masz na myśli w funkcji, mainie? Sory ale za bardzo nie rozumiem :( - ByQQ 2017-04-21 12:01

Pozostało 580 znaków

2017-04-21 11:51
0

Ale po co w ogóle tutaj takie cuda na kiju jak *wskaznik++? Nie umiesz używać operatora []? Przecież to można napisać po ludzku z użyciem prostej pętli for.


Na PW przyjmuje tylko (ciekawe!) zlecenia. Masz problem? Pisz na forum, nie do mnie.

Pozostało 580 znaków

2017-04-21 12:51
0

Pomijajac to, że nie wiesz jakie są rozmiary buforów wejściowych, modyfikujesz buffor wejsciowy line i nie zwracasz ilości skopiowanych lini, to chyba chodziło Ci o coś takiego:

void parse(char *line, char **line_ptrs, char *file_name) {
    assert(line != 0);
    assert(line_ptrs != 0);
    assert(file_name != 0);
    // silently assumes that line_ptrs is big enought to hold cstring pointers from line
 
    size_t idx = 0;
    bool in_substring = false;
    for ( ; line[idx] != '\0'; ++idx) {
        // found ">>", go to file parsing
        if (line[idx] == '>' && line[idx+1] == '>') {
            break;
        }
 
        // whitespaces
        if (line[idx] == ' ' || line[idx] == '\t' || line[idx] == '\n') {
            in_substring = false;
            line[idx] = '\0';
            continue;
        }
 
        // first not whitespace
        if (!in_substring) {
            *line_ptrs++ = line + idx;
            in_substring = true;
            continue;
        }
    }
 
    // skip whitespaces
    for ( ; line[idx] == ' ' || line[idx] == '\t' || line[idx] == '\n' ||
            line[idx] == '>';
            ++idx) {
        // pass
    }
 
    // it will copy trailing whitespaces too...
    strcpy(file_name, line + idx);
}
edytowany 9x, ostatnio: nalik, 2017-04-21 12:59
Dzięki za kod ale tego nie potrzebuje. Chciałbym aby mój działał poprawnie. Nie mogę w żaden sposób tego ostatniego wyrazu przekopiować do innej tablicy char? - ByQQ 2017-04-21 13:12
Możesz, ale u siebie tego nie robisz. Nie rozumiesz jak działają wskaźniki i argumenty funkcji. - nalik 2017-04-21 13:14
Dokładnie. Nie da się tego nie zauważyć... Jakimś dobrym poradnikiem jesteś w stanie poratować? - ByQQ 2017-04-21 13:46

Pozostało 580 znaków

2017-04-21 15:43
0

Problem rozwiązany. Dziękuję za pomoc :)

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0