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

Wypisywanie liter alfabetu z zakresu podanego przez użytkownika

VPS Starter Arubacloud
+1 głos
487 wizyt
pytanie zadane 23 grudnia 2021 w C i C++ przez MKolaj15 Bywalec (2,270 p.)

Witam, mam do napisania program, w którym proszę użytkownika o podanie dowolnej liczby par znaków. Koniec ich pobierania ma nastąpić po wpisaniu przez użytkownika "stop". Mam utworzyć wektor string'ów, który będzie słóżył jako wektor zakresów.

Przykład działania kodu:

Użytkownik wpisuje:

a b

b a

c g

g c

x

stop

 

Wynik:

ab

ab

cdefg

cdefg

x

 

Jak widać wypisywnie liter ma działać tak samo, bez względu na kolejność podanych znaków. Mam też wykorzystać funkcję getline() jako warunek pętli. Oto co udało mi się dotychczas napisać:

#include <iostream>
#include <string>
#include <vector>

auto main() -> int
{
        std::string a,b;
        auto vec = std::vector<std::string>{"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};

        std::cout<<"Podaj dwie litery: "<<std::endl;

        while(a!="stop")
        {
                std::getline(std::cin, a, ' ');
                std::getline(std::cin, b, ' ');

                for(size_t i = 0; i < vec.size(); i++)
                {
                        if(a == vec[i])
                        {
                                while(vec[i] != b)
                                {
                                        std::cout<<vec[i];
                                        i++;
                                }
                        std::cout<<std::endl;
                        i = 0;
                        }


                }
        }

return 0;
}

Szczerze to nie wiem do końca jak poprawnie wykorzystać te getline'ny. Byłbym bardzo wdzięczny, gdyby ktoś pomógł mi poprawić ten kod. Z góry dzięki!

2 odpowiedzi

+2 głosów
odpowiedź 23 grudnia 2021 przez profesorek96 Szeryf (91,420 p.)
wybrane 24 grudnia 2021 przez MKolaj15
 
Najlepsza

Myślę że autorowi zadania chodziło o to aby wyżyć getline w warunku pętli while. Dodatkowo w warunku sprawdzam czy wczytany ciąg znaków nie jest równy napisowi "stop". Dopiero wewnątrz pętli rozdzielam tak wczytany ciąg znaków na dwie składowe według znaku spacji. Co ciekawe rozdzielanie napisu realizowane jest również na funkcji getline.

Myślę że nie ma co więcej pisać, załączam poniżej kod rozwiązujący twój problem:

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
int main() 
{
	std::string input;
	while(std::getline(std::cin,input)&&input!="stop")
	{
		std::stringstream ss(input);
		std::string item;
		std::vector<std::string> elems;
		while (std::getline(ss, item, ' ')) {
    		elems.push_back(item);
		}
		sort(elems.begin(),elems.end());
		if(elems.size()>1)
		{
			char start=elems[0][0];
			char stop=elems[1][0];
			while(start<=stop)
			{
				std::cout<<start;
				start++;
			}
		}
		else if(elems.size()==1)
		{
			std::cout<<elems[0];
		}
		std::cout<<"\n";
	}
	return 0;
}

Rozwiązanie tego zadania oparłem o fakt że litery są w jakiś sposób kodowane. Najprostszy sposób kodowania to tak zwana tablica ASCII. Każda z liter alfabetu angielskiego ma jakiś swój numer np mała litera a ma wartość 97 zaś b ma 98 i tak dalej aż do literki z. Podobnie jest z dużymi literami.

2
komentarz 24 grudnia 2021 przez j23 Mędrzec (194,920 p.)
Z tym sortem dla dwóch liter to przesadziłeś :)
komentarz 24 grudnia 2021 przez MKolaj15 Bywalec (2,270 p.)

Wielkie dzięki za pomoc! Wszystko jest w miarę jasne, oprócz jednej rzeczy. Mógłbyś mi wyjaśnić jak działa getline() w tej linijce?

while (std::getline(ss, item, ' '))

Jak wspominałem nie mam za bardzo doświadczenia z tą funkcją i myślałem, że jako pierwszy argument może przyjmować tylko std::cin. Możesz mi wyjaśnić jak to działa, że jest tam zmienna ss?

komentarz 24 grudnia 2021 przez profesorek96 Szeryf (91,420 p.)

@j23, No może troszkę xd 

1
komentarz 24 grudnia 2021 przez profesorek96 Szeryf (91,420 p.)
@MKolaj15, Zasadniczo to getline jako pierwszy argument przyjmuję referencję na obiekt typu istream. Zapytasz pewnie dlaczego działa jak podałem mu obiekt o nazwie ss, który jest typu stringstream. Otóż mamy tutaj do czynienia z czymś takim jak polimorfizm. Klasa stringstream jest w relacji dziedziczenia z klasą istream (nie bezpośrednio). Po więcej szczegółów odsyłam do dokumentacji klasy stringstream:

https://www.cplusplus.com/reference/sstream/stringstream/

Powyższy link przedstawia właśnie tą hierarchię. Polecam również zapoznać się z dokumentacją funkcji getline:

https://www.cplusplus.com/reference/string/string/getline/

Mam nadzieję że wyjaśniłem.
2
komentarz 24 grudnia 2021 przez j23 Mędrzec (194,920 p.)

Troszkę uprościłem kod:

int main(void)
{
    std::string line;
    char c1, c2;

    while (std::getline(std::cin, line, '\n') && line != "stop") {
        std::istringstream is(line);

        is >> c1;
        
        c2 = c1;

    	if (is >> c2 && c1 > c2) std::swap(c1, c2);
		for (; c1 <= c2; ++c1) std::cout << c1;
    	std::cout << '\n';
    }
}

 

2
komentarz 24 grudnia 2021 przez MKolaj15 Bywalec (2,270 p.)
Dzięki wielkie wam za pomoc!
+1 głos
odpowiedź 25 grudnia 2021 przez VBService Ekspert (251,210 p.)
edycja 25 grudnia 2021 przez VBService

Do pobrania danych od użytkownika możesz wykorzystać, np: indexing string

 

przykład  [ on-line ]

#include <iostream>
#include <string>

int main()
{
    std::string a="";
    
    std::cout<<"Podaj dwie litery: ";
    while (std::getline(std::cin, a) && a != "stop")
    {
        unsigned int start=0, stop=0;
        
        switch (a.length())
        {
            case 3: start = (int)a[0]; stop = (int)a[2]; break;
            case 2: start = (int)a[0]; stop = (int)a[1]; break;
            case 1: start = stop = (int)a[0]; break;
        }
        
        if (start > stop)
            start ^= stop ^= start ^= stop;
        
        for (int i = start; i <= stop; i++)
            std::cout << char(i);
        
        std::cout << std::endl;
        std::cout<<"Podaj dwie litery: ";
    }
    
    return 0;
}

przykład nie obejmuje

Mam utworzyć wektor string'ów, który będzie słóżył jako wektor zakresów.

Podobne pytania

0 głosów
1 odpowiedź 1,076 wizyt
0 głosów
1 odpowiedź 270 wizyt
0 głosów
2 odpowiedzi 8,991 wizyt

92,452 zapytań

141,262 odpowiedzi

319,078 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...