Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Porównanie łańcucha znaków z tablicą dwuwymiarową jako warunek pętli.

Ostatnio zmodyfikowano 2017-04-06 19:36
Autor Wiadomość
0x07
Temat założony przez niniejszego użytkownika
Porównanie łańcucha znaków z tablicą dwuwymiarową jako warunek pętli.
» 2017-04-06 18:01:47
Cześć.

Staram się napisać program, który będzie wczytywał w pętli znaki z klawiatury i zapisywał je do osobnych tablic, aby później móc je porównać. W tym celu stworzyłem tablicę dwuwymiarową, ale nie mam zielonego pojęcia jak ustawić warunek pętli, żeby wpisanie pojedynczego znaku kończyło pętlę (np. "q" kończy pętlę, ale "quit" już nie). Mój kod wygląda mniej więcej tak:

const int rozm = 20;
char ch[rozm][30];
    int i = 0;
    std::cin >> ch;
    while (ch != "q")
    {
        i++;
        std::cin >> ch;
    }

Program kompiluje się poprawnie i nie wyświetla żadnych błędów, ale wczytanie "q" nie przerywa pętli. Wydaje mi się, że źle ustanowiłem warunek. Czy ktoś mógłby dać jakąś wskazówkę co robię źle (nie proszę o prawidłowy kod).

Pozdrawiam seredecznie,
0x07
P-159887
latajacaryba
» 2017-04-06 18:12:39
cin >> ch;
a powinno być
C/C++
cin >> ch[ x ][ y ];
while( ch[ x ][ y ] != 'q' )

W ogóle nie mam pojęcia jak ten kod ma prawo się kompilować. Musisz poznać zależność między znakiem a c-stringiem
cstring to ciąg znaków, który na końcu zero - znak
null
natomiast znak char, to np. zwykłe 'a' - tu nie ma żadnego zera.

Kiedy masz tablice znaków:
C/C++
char tab[ 50 ];
cin >> tab;
// WPISALEM: ALA MA KOTA
cout << tab;

Tablica ma pojemność 50 znaków. Jak widzisz, "Ala ma kota" to 11 znaków (spacje też sie liczą). Ale jest jeszcze znak zera, null. W takim razie cały string ma długość 12 znaków. Czyli długość tekstu + 1
Ty masz za to tablicę dwuwymiarową (czyli tablicę tablic). Tak więc zastanów się, co chcesz osiągnąć pisząc:
cin >> ch;
Powinieneś napisać (jeśli chcesz wpisać c-stringa czyli zmienną tekstową)
cin >> ch[ x ];
Jeśli znak:
cin >> ch[ x ][ y ];

Więcej na ten temat: http://cpp0x.pl/kursy/Kurs-C++/Ciagi-znakow-lancuchy/299


ps, kod na forum wstawiaj w znaczniki:
[cpp] TWOJ KOD TUTAJ [/cpp]

P-159888
0x07
Temat założony przez niniejszego użytkownika
» 2017-04-06 18:36:23
Dziękuje za odpowiedź. Trop jest wielce pomocny, jednakże zastosowanie 'q' zamiast "q" sprawia, że do przerwania pętli wystarczy użyć q gdziekolwiek we wpisywanym wyrazie. Warunkiem sine qua non mojego programu ma być przerwanie pętli po wpisaniu pojedynczego "q" z możliwością użycia go w innych wyrazach (np. "quit"), bez zakończenia pętli.

Edit: W moim programie używałem
cin >> ch[ i ]
, ale przy przepisywaniu przypadkowo pominąłem.
P-159890
latajacaryba
» 2017-04-06 19:06:20
Trop jest wielce pomocny, jednakże zastosowanie 'q' zamiast "q" sprawia, że do przerwania pętli wystarczy użyć q gdziekolwiek we wpisywanym wyrazie.
To zależy co do czego porównujesz. Jeśli napiszesz tak:
while( ch[ 0 ][ 0 ] != 'q' )
to sprawdzana będzie pierwsza litera - o indeksie 0,0
Natomiast domyślam się, że Ty chcesz wpisywać wyraz i jeśli będzie to pojedyncza litera 'q' to petla ma być przerywana, jeśli zaś 'quit', to ma sie dalej odbywać.
Chciałbym zauważyć, że ch[0][0] to ZNAK, natomiast ch[0] to cale slowo/zdanie (c-string)
Dlatego nie możesz porównywać ch[0] == 'q'
Bo 'q' to znak, ale już  "q"  to c-string - bo zapisany w cudzysłowiu "" , a nie '' .
Możesz porównywac tylko znaki do znaków i cstringi do cstringów. Tak więc:

C/C++
ch[ 20 ][ 10 ]; // tablica 20x10
ch == 'a' // zle, ch jest dwuwymiarowa, więc chcesz porównać tablicę tablic do znaku - bezsens
ch == "a" // tez bezsens, tablica tablic, czyli tablica cstringow porownywana do cstringa - tylko nie wiadomo ktory porownac do ktorego, skoro w tablicy //jest 20 cstringow

ch[ 0 ] == 'a' // zle, cstring porownujesz do znaku
ch[ 0 ] == "a" // dobrze, cstring porownujesz do cstringa (pamietaj, ze w tym wypadku tu beda 2 znaki - a oraz null - tak jak zwykle przy c-stringach)

ch[ 0 ][ 0 ] == 'a' // dobrze, znak porownujesz do znaku, bo ch[0][0] to pierwszy indeks w pierwszej tablicy.
ch[ 0 ][ 0 ] == "a" // nonsens, chcesz porownac znak z indeksu pierwszego pierwszej tablicy do c-stringa

Tak więc jeśli chcesz, by twój program działał zrób tak:
C/C++
while( ch[ j ] != "q" ) // dopoki calym cstrigiem(slowem, zdaniem) wpisanym przez uzytkownika nie bedzie jedna litera - q (zamiast i wpisałem j, bo forum //formatuje to jako tekst pochyły)
Możesz również zrobić tak, że jeśli pierwsza litera w danym cstringu bedzie sie równała q to coś tam:

if(ch[j][0] == q) // tablica i, indeks 0 - czyli pierwszy - numerujemy od zera
P-159896
Luq
» 2017-04-06 19:09:28
Do porównywania cstringów skorzystaj z funkcji
strcmp
 z
< cstring >
P-159898
0x07
Temat założony przez niniejszego użytkownika
» 2017-04-06 19:17:53
Właśnie w tym rzecz, że ja już tak zrobiłem w swoim programie i od dłuższego czasu głowię się co jest nie tak. Oto cały kod:
C/C++
#include <iostream>
#include <cctype>
#include <cstring>
int main()
{
    std::cout << "Pisz sobie tekst (pojedyncze q konczy):\n";
    char ch[ 20 ][ 30 ];
    int j = 0;
    std::cin >> ch[ j ];
    while( ch[ j ] != "q" )
    {
        j++;
    }
    return 0;
}

Z kolei, jeżeli zamienię warunek na
while( ch[ j ] == "q" )
 to program zakończy się po wpisaniu jakiegokolwiek znaku. Dodam tylko, że ten sam co u góry warunek zadziała przy zastosowaniu obiektu std::string (przy zastosowaniu drobnych poprawek). No, tyle tylko, że ja muszę użyć do tego tablic.
P-159899
Luq
» 2017-04-06 19:22:09
Nie możesz porównywać cstringów operatorami == i !=, bo porównujesz adresy stringów zamiast ich zawartości.
Tak jak pisałem wyżej użyj funkcji
strcmp
P-159900
0x07
Temat założony przez niniejszego użytkownika
» 2017-04-06 19:36:04
No przecież, zapomniałem o strcmp()! Dzięki Wam wielkie za pomoc i za cierpliwość. Wszystko działa ładnie pięknie, a ja utrwaliłem wiedzę dot. łańcuchów w C. Teraz już nigdy nie zapomnę jak je porównywać. Jeszcze raz dzięki.

Pozdrawiam
0x07
P-159905
« 1 »
  Strona 1 z 1