Wczytywanie „znak po znaku” cyfr oraz wyrazów w C++

Czasami podczas programowania musimy w specyficzny sposób wczytać jakieś znaki wprowadzane przez użytkownika tak aby potem wykonać na nich operacje. Mogą to być na przykład liczby, które trzeba wczytać cyfra po cyfrze i każdą z osobna zapisać przykładowo w osobnym elemencie tablicy lub po prostu jakiś wyraz, który musimy wczytać litera po literze i również każdy znak zapisać osobno. Jak zatem zrobić to sprawnie i szybko?

Fot: Paul Williams, CC BY-ND 2.0.

Fot: Paul Williams, CC BY-ND 2.0.

Problem ten można rozwiązać na kilka sposobów, należy jednak pamiętać, że nie możemy tutaj przypisać danego wyrazu bądź liczby zapisanej w jakiejś zmiennej (obiekcie) bezpośrednio do tablicy typu char, jak często myśli wiele osób. W artykule „Tablica typu Char – Jak w prosty sposób przechowywać ciągi znaków?” szczegółowo opisałem iż można tak zrobić tylko i wyłącznie w momencie w którym dany wyraz zapisujemy bezpośrednio do tworzonej właśnie tablicy.

scanf()

Przy wczytywaniu danych „znak po znaku” możemy zastosować wspomnianą już tablicę char oraz funkcję scanf() opisaną bardziej szczegółowo w artykule „Wczytywanie i wypisywanie danych w C++ za pomocą Scanf i Printf – szybsza alternatywa dla cout oraz cin„. Jak to zrobić?

Po uruchomieniu powyższego kodu i podaniu jakiegoś wyrazu bądź liczby każda litera/cyfra zostanie zapisana w oddzielnej komórce tablicy tab, a na końcu za pomocą pętli zostanie wyświetlony cały łańcuch znaków.

Udało nam się zapisać jakiś ciąg znaków w tablicy, ale jak wczytać na przykład liczby?

Tutaj należy pamiętać, że każdy znak typu char to tak naprawdę kod ASCII. Od wczytanej liczby wystarczy więc odjąć 48 i w ten sposób uzyskamy liczbę na której możemy wykonywać zwykłe działania arytmetyczne:

getchar()

Przy wczytywaniu danych „znak po znaku” zastosujemy funkcję getchar(), za pośrednictwem której będziemy pobierać z wejścia pojedyncze znaki.

Po uruchomieniu powyższego kodu i podaniu jakiegoś wyrazu bądź liczby każda litera/cyfra zostanie zapisana w oddzielnej komórce tablicy tab, a na końcu za pomocą pętli zostanie wyświetlony cały łańcuch znaków.

Udało nam się zapisać jakiś ciąg znaków w tablicy, ale jak wczytać na przykład liczby?

Tutaj należy pamiętać, że każdy znak typu char to tak naprawdę kod ASCII. Od wczytanej liczby wystarczy więc odjąć 48 i w ten sposób uzyskamy liczbę na której możemy wykonywać zwykłe działania arytmetyczne. Proszę zwrócić tutaj uwagę, że dane te należy wczytać do tablicy na przykład typu int:

, , , , , , , ,

  • Czy aby na pewno scanf(„%s”, &tab); jest prawidłowo? chyba powinno być scanf(„%s”, tab);, a żeby było
    bezpiecznie to scanf(%5s, tab);
    kolejna rzecz – to scanf jest w stdio.h, która nie jest dołączana, powinno być (skoro pisane w c++)
    #include
    Dodatkowo scanf i printf niekoniecznie są szybsze od cin si cout, to zależy od implementacji oraz, czy jest synchronizacja miedzy cin/cout i stdin/stdout, jesli jej nie ma cin i cout działać będą dużo szybciej.

    • Na moim kompilatorze Xcode zadziałała wersja zarówno z referencją (scanf(„%s”, &tab)) oraz bez (scanf(„%s”, tab)), faktycznie scanf jest zaimplementowany w cstdio.h ale nie dołączenie tej biblioteki nie wpływa na działanie programu (przynajmniej na Xcode) nie mniej jednak dla bezpieczeństwa taki include można zrobić. Co do szybkości to chodzi o to, że przy takich prostych „algorytmicznych” programach scanf i printf działa szybciej (nie w tym rzecz, żeby rozpisywać się na temat różnych przypadków). Dziękuję za uwagi ;)

      • Zrób to samo z tablicą alokowaną dynamicznie – będziesz wiedział, które jest złe. To, że zadziałało na tablicy statycznej – to przypadek.

        • Faktycznie, sprawdziłem w dokumentacji nie powinno tam być referencji. Dzięki ;)

    • Jacek Szempliński

      Tomku, Szybkość działania scanf i printf w porównaniu do cin i cout jest zależna od platformy i konkretnego przypadku. Jeśli uruchomimy program z przekierowaniem we/wy możemy zamiast z klawiatury czytać z pliku, a zamiast na monitor wysyłać do pliku. Tak działają wszelkiego rodzaju sprawdzarki np. na konkursach. Przetestowałem to zarówno na serwerach sprawdzających jak i na własnym komputerze z Windowsem 7 64bit. Synchronizację miałem wyłączoną. Scanf działa ok 2 razy szybciej, Printf działa ok. 5 razy szybciej. Od tego może zależeć czy zadanie będzie zaliczone. Te same testy wykonane z wysyłaniem na monitor wykazały, że cout działa szybciej.