[C++] program zamieniający tekst na pisany wielkimi literami

diego_maradona
Użytkownik
Użytkownik
Posty: 184
Rejestracja: 16 cze 2010, o 00:59
Płeć: Mężczyzna
Lokalizacja: Kraków
Podziękował: 80 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: diego_maradona » 8 sie 2011, o 00:20

Kod: Zaznacz cały

// uppercase_letter.cpp : main project file.


#include "stdafx.h"
#include <iostream>
#include <cctype>

using namespace std;

int i;

void enter ( char str[] );
void toUppercase ( char str[] );
void print (char str[] );



int main()
{
    char text[999];
	

	cout<<"Program converts letters in your text to uppercase \n ";

	enter ( text );
	cout<<endl;
	toUppercase ( text );
	cout<<endl;
	print ( text );
	cout<<endl;




	cout<<endl;
	system("PAUSE");
}

void enter ( char str[] )
{
	for ( i= 0 ; i < 999 ; i++)
	{	cin >> str[i];
	 if (str[i]== '\n')
		break;
	}
}

void toUppercase ( char str[] )
{
	for ( i = 0 ; i < 999 ; i++)
		str[i] = static_cast<char>(toupper( str[i] ));
}

void print ( char str[] )
{
	for (i = 0 ; i < 999 ; i++)
		cout<< str[i] << endl;
}

po naciśnięciu klawisza enter program powinien wyświetlić wszystkie wpisane wcześniej litery jako WIELKIE.
Problem w tym , że tak nie jest , wygląda na to że warunek w if'ie jest zawsze prawdą . Jak rozgryźć tę instrukcję warunkową?

void_t
Użytkownik
Użytkownik
Posty: 103
Rejestracja: 14 maja 2011, o 18:25
Płeć: Mężczyzna
Pomógł: 26 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: void_t » 8 sie 2011, o 10:57

Powiem tak: piszesz na siłę w tym C++.
Niepotrzebnie IMO, ale proszę: tutaj jest kod (21 linii), który rozwiązuje to co tam próbowałeś zrobić w 58 liniach.

Kod: Zaznacz cały

#include <iostream>
#include <cstring>
#include <cstdio>

#define BUFSIZ 1024
#define to_upper(p) ((p >= 'a' && p <= 'z') ? (p & ~0x20) : p)

int main(int argc, char **argv)
{
	char buf[BUFSIZ];
	char *p;

	std::cout << "Program converts letters in your text to uppercase\n";
	
	memset(buf, 0, BUFSIZ);
	fgets(buf, BUFSIZ - 1, stdin);
	
	for (p = buf; *p; *p = to_upper(*p), p++);
	printf("%s\n", buf);
}
BTW, tak: tutaj też mamy ładną mieszankę funkcji C z C++.
PS. Makro to_upper robi dokładnie to samo co (chyba) funkcja toupper(), z tym, że teraz wiesz jak.
Ostatnio zmieniony 8 sie 2011, o 20:10 przez void_t, łącznie zmieniany 1 raz.

PMichalak
Użytkownik
Użytkownik
Posty: 125
Rejestracja: 29 paź 2009, o 20:03
Płeć: Mężczyzna
Lokalizacja: Kalisz
Podziękował: 1 raz
Pomógł: 16 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: PMichalak » 8 sie 2011, o 11:09

Myślę, że taki kod jest o wiele czytelniejszy.

Kod: Zaznacz cały

///Pawel Michalak
#include<iostream>
#include<algorithm>
using namespace std;

const char d = 'A' - 'a';

char toUpper(char c)
{
    if('a' <= c and c <= 'z') return c+d;
    else return c;
}

int main()
{
    string s;
    cin >> s;
    for(string::iterator i = s.begin(); i != s.end(); ++i)
        *i = toUpper(*i);
    cout << s;
    return 0;
}
albo taki:

Kod: Zaznacz cały

///Pawel Michalak
#include<iostream>
#include<algorithm>
using namespace std;

const char d = 'A' - 'a';

char toUpper(char c)
{
    if('a' <= c and c <= 'z') return c+d;
    else return c;
}

int main()
{
    string s;
    cin >> s;
    transform(s.begin(), s.end(), s.begin(), toUpper);
    cout << s;
    return 0;
}

void_t
Użytkownik
Użytkownik
Posty: 103
Rejestracja: 14 maja 2011, o 18:25
Płeć: Mężczyzna
Pomógł: 26 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: void_t » 8 sie 2011, o 12:15

Śmiem powątpiewać w czytelność podobnie jak w wydajność.

Kod: Zaznacz cały

const char d = 'A' - 'a';
Przecież to i tak zawsze wynosi 0x20.

Poza tym:

Kod: Zaznacz cały

char toUpper(char c)
Zakładając że korzystasz z gcc/MinGW <= 4.4 to nie będzie wymuszone na niej inline, w zwiazku z czym za każdym razem zobaczysz w kodzie wynikowym kosztowne 'call'.
Oczywiście w tym przypadku nie ma to znaczenia, bo input będzie i tak krótki. Nie ma jednak potrzeby prezentować takiego stylu programowania, bo jest on poprostu zły.

Dalej: kto jeszcze używa w instrukcjach warunkowych operatorów 'and', 'or', etc?

Kod: Zaznacz cały

string s;
String? Owszem. To jest akurat dobry pomysł, ale już ten iterator niekoniecznie.

No ale tego właśnie niestety uczy C++.

diego_maradona
Użytkownik
Użytkownik
Posty: 184
Rejestracja: 16 cze 2010, o 00:59
Płeć: Mężczyzna
Lokalizacja: Kraków
Podziękował: 80 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: diego_maradona » 8 sie 2011, o 16:57

Dzięki , ale nie pytałem o bardziej optymalne algorytmy , tylko o to, dlaczego funkcja if jest zawsze prawdziwa. Przespałem się z tym zadaniem, i zauważyłem że operator common input (cin ) pomija nie tylko spacje ale także wciśnięcia klawisza enter(i wszystkie inne "puste" znaki ).
Zamieniłem na cin.get i teraz if działa jak należy, ale to nie koniec moich zmartwień, niby program teraz spełnia swoją funkcję, ale skąd te dziwne znaki w konsoli? Zamieniłem jeszcze rozmiar tablicy text na 41, bo przy 999 jest totalny bałagan.

http://imageshack.us/photo/my-images/593/input.png

void_t
Użytkownik
Użytkownik
Posty: 103
Rejestracja: 14 maja 2011, o 18:25
Płeć: Mężczyzna
Pomógł: 26 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: void_t » 8 sie 2011, o 17:13

No temu, że nie wyzerowałeś pamięci, to że napisałeś

Kod: Zaznacz cały

char text[999];
nie znaczy, że w przestrzeni, która zostanie przydzielona tej tablicy jest pusto. Musisz taki bufor wyczyścić, używając chociażby instrukcji memset.

diego_maradona
Użytkownik
Użytkownik
Posty: 184
Rejestracja: 16 cze 2010, o 00:59
Płeć: Mężczyzna
Lokalizacja: Kraków
Podziękował: 80 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: diego_maradona » 8 sie 2011, o 17:58

Ok, pozbyłem się tego problemu na dwa sposoby

Pierwszy- liczenie znaków i ograniczenie przez tą liczbę powtórzeń pętli znajdującej się w funkcji print.

Kod: Zaznacz cały

#include "stdafx.h"
#include <iostream>
#include <cctype>

using namespace std;

int i,signs;


void enter ( char str[] );
void toUppercase ( char str[] );
void print (char str[] );



int main()
{
    char text[999];
	

	cout<<"Program converts letters in your text to uppercase \n ";

	enter ( text );
	cout<<endl;
	toUppercase ( text );
	cout<<endl;
	print ( text );
	cout<<endl;




	cout<<endl;
	system("PAUSE");
}

void enter ( char str[] )
{
	
	
	for ( i= 0 ; i < 999 ; i++)
	{	
		
		cin.get(str[i]);
	 if (str[i] == '\n')
		break;
	 signs++;
	}
}

void toUppercase ( char str[] )
{
	for ( i = 0 ; i < 999 ; i++)
		str[i] = static_cast<char>(toupper( str[i] ));
}

void print ( char str[] )
{
	for (i = 0 ; i < signs ; i++)
		cout<< str[i] ;
}
drugi- dodanie funkcji initialise

Kod: Zaznacz cały

// uppercase_letter.cpp : main project file.


#include "stdafx.h"
#include <iostream>
#include <cctype>

using namespace std;

int i;

void initialise (char str[]);
void enter ( char str[] );
void toUppercase ( char str[] );
void print (char str[] );



int main()
{
    char text[999];
	

	cout<<"Program converts letters in your text to uppercase \n ";

	initialise (text);
	enter ( text );
	cout<<endl;
	toUppercase ( text );
	cout<<endl;
	print ( text );
	cout<<endl;




	cout<<endl;
	system("PAUSE");
}

void enter ( char str[] )
{
	
	
	for ( i= 0 ; i < 999 ; i++)
	{	
		
		cin.get(str[i]);
	 if (str[i] == '\n')
		break;
	 
	}
}

void toUppercase ( char str[] )
{
	for ( i = 0 ; i < 999 ; i++)
		str[i] = static_cast<char>(toupper( str[i] ));
}

void print ( char str[] )
{
	for (i = 0 ; i < 999 ; i++)
		cout << str[i] ;
}

void initialise ( char str[] )
{
	for (i = 0 ; i < 999 ; i++)
		 str[i]=0;
}


Wciąż jednak nurtuje mnie to skąd się wzięły wcześniej te tajemnicze znaki i dlaczego akurat takie, jakaś wiadomość z zaświatów czy co? :D

void_t
Użytkownik
Użytkownik
Posty: 103
Rejestracja: 14 maja 2011, o 18:25
Płeć: Mężczyzna
Pomógł: 26 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: void_t » 8 sie 2011, o 18:15

Napisałem w moim ostatnim poście: dlatego, że przydzielona pamięć jest zwykle zaśmiecona jakimiś danymi pozostawionymi np przez inny program.

soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1822 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: soku11 » 8 sie 2011, o 19:07

@void_t:
1. Pisze się w takim języku, w jakim jest wygodniej.
2. Ilość linijek kodu nie jest żadnym wyznacznik dobrze napisanego programu.
3. Funkcja to_upper, toUpper itd - jest ona już napisana w cctype. Nie widzę sensu w pisaniu jej od nowa. W dodatku stosowanie magicznych liczb (0x20) i operacji bitowych jest tylko zaciemnieniem kodu.
4. W C++ do tworzenia stałych stosuje się static const, a zamiast tego typu makr stosuje się funkcje inline.
5. W C++ do obsługi strumieni stosuje się cout/cin.
5. Co jeśli ktoś poda więcej niż 1024 znaki?
6. Jaki jest sens wpychania wszystkiego w jedną linię (18 linijka)?
7. printf jako pierwszego argumentu wymaga ciągu formatującego.
8. Zmienne powinno się deklarować w jak najwęższym zakresie (patrz *p).
8. Przedwczesna optymalizacja jest źródłem wszelkiego zła. Nie jesteśmy w antycznych czasach, kiedy trzeba analizować asma w poszukiwaniu wydajności. Dodatkowo kompilatory są na tyle inteligentne, że potrafią optymalizować wywołania prostych funkcji. Zdecydowanie lepiej jest napisany kod użytkownika PMichalak. Szczególnie ten drugi - w stylu C++ korzystając z jego zalet, bez zbędnych zabaw i kombinacji. Tylko niepotrzebnie definiuje ponownie toUpper. Kod jest czysty i łatwy w utrzymaniu (poza kilkoma szczególikami) - według mnie.
9. Rzeczywiście trochę dziwnie używać and i or. Ale jak jemu tak wygodnie, to w czym problem?
10. Co jest złego w zastosowaniu iteratora?
11. C++ uczy prawidłowego obiektowego podejścia do programowania. Uwierz, że nie wszystko różne od C jest złe. Zaraz poleci hasło żeby pisać TYLKO w prostym notatniku i pisać ręcznie makefile'a (swoją drogą make to też już antyczne narzędzie). Każdemu na początku swojej przygody z programowaniem wydaje się, że istnieje wyłącznie jeden poprawny język. Z doświadczeniem to na szczęście przechodzi :)

void_t
Użytkownik
Użytkownik
Posty: 103
Rejestracja: 14 maja 2011, o 18:25
Płeć: Mężczyzna
Pomógł: 26 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: void_t » 8 sie 2011, o 20:09

Ad1. Zdecydowanie. Ale nie zawsze wybór języka jest właściwy.
Ad2. Nikt nie mówił, że ilość linijek wyznacza cokolwiek. Stwierdziłem jedynie oczywisty fakt.
Ad3. No jest, to prawda - napisałem bo taką miałem ochotę.
Ad4. True.
Ad5. True.
Ad5b. Zostaną przetworzone tylko 1023 znaki. Autor zapisał statyczny bufor, zrobiłem to i ja.
Ad6. A co to za różnica? Zacytuję:
Ale jak jemu tak wygodnie, to w czym problem?
Ad7. True. To błąd bezpieczeństwa. Za chwile poprawię.
Ad8. Najwęższym zakresie?
Ad8b. Bez wątpienia Knuth miał rację. Ale jesteśmy dalej w czasach w których w dalszym ciągu człowiek jest mądrzejszy od kompilatora i potrafi stworzyć (w pewnych przypadkach) wydajniejszy kod.
Ad10. Właściwie to nic jeśli mowa o C++
Ad11. Polemizowałbym. Natomiast nie powiedziałem jakoby cokolwiek innego od C jest złe. Pisać w prostym notatniku? Chyba bym nie widział na oczy po 10 minutach. Makefile? Nie, takie rzeczy się generuje. Ponownie: nie mówię, że istnieje jeden poprawny język. Ale twierdzę, że C > C++.

Z mojej strony EOT.

abc666

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: abc666 » 9 sie 2011, o 22:22

Hmm \(\displaystyle{ C > C++}\) ale \(\displaystyle{ C \subset C++}\)
Ciekawa własność.

Awatar użytkownika
Quaerens
Użytkownik
Użytkownik
Posty: 2489
Rejestracja: 5 wrz 2007, o 13:36
Płeć: Mężczyzna
Podziękował: 439 razy
Pomógł: 181 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: Quaerens » 10 sie 2011, o 10:19

void_t, pisząc C>C++ masz na myśli, że C jest twoim zdaniem potężniejszy czy tam praktyczniejszy? Nie wiem jak taką relację tłumaczyć

void_t
Użytkownik
Użytkownik
Posty: 103
Rejestracja: 14 maja 2011, o 18:25
Płeć: Mężczyzna
Pomógł: 26 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: void_t » 10 sie 2011, o 10:46

Mam na myśli, że C jest bardziej użyteczny, prostszy, a co za tym idzie pozbawiony zbędnych kruczków składniowych i idiotycznych wieloznaczności. Jeśli nie wydaje się nikomu abym wyrażał swoje myśli precyzyjnie, proponuję poczytać trochę na stackoverflow - ktoś kiedyś zrobił bardzo dobre podsumowanie (aktualnie zgubiłem urla).

wszamol
Użytkownik
Użytkownik
Posty: 490
Rejestracja: 7 maja 2009, o 22:01
Płeć: Mężczyzna
Podziękował: 1 raz
Pomógł: 64 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: wszamol » 10 sie 2011, o 13:20

void_t pisze:Mam na myśli, że C jest bardziej użyteczny, prostszy.
No tak, ale to jest Twoje zdanie, co kto lubi a to, że kiedyś ktoś zrobił porównanie... co z tego jak np. mnie lepiej pisze się w c++. To jest kwestia własnych upodobań i tyle, ale tak jak wyżej powiedzieli, c++ jest rozwinięciem c, więc nie wiem jak czyste c może być bardziej użyteczne

soku11
Użytkownik
Użytkownik
Posty: 6607
Rejestracja: 16 sty 2007, o 19:42
Płeć: Mężczyzna
Podziękował: 119 razy
Pomógł: 1822 razy

[C++] program zamieniający tekst na pisany wielkimi literami

Post autor: soku11 » 10 sie 2011, o 23:33

Kopiowałem numery i mi się kilka razy powtórzyło - heh.
2. Napisałeś w drugim zdaniu pierwszego swojego posta o ilości linijek. Po prostu odczytałem to jako skrytykowanie kodu, bo ma więcej linijek.
5b. Skoro podałeś swoje rozwiązanie, to powinno być ono poprawne. Nie wiem czemu tłumaczysz się kodem autora. Jak masz dłuższy tekst, to po prostu zadanie nie będzie wykonane poprawnie.
6. Stwierdzenie napisałem w kontekście używania konstrukcji and i or. Wszystko w jednej linijce zaciemnia kod przez co staje się on trudniejszy w utrzymaniu. Rada na przyszłość.
8. Używasz p wyłącznie w pętli - zdefiniuj je w pętli a nie na początku funkcji.
8b. Z ciekawości - podasz przykład, w którym ktoś szukał wydajności poprzez modyfikację kodu asm bądź używanie nieprzenośnych wstawek asma?
10. Nie rozumiem. Wytykasz błąd użycia iteratora w przypadku C++. Temat dotyczy C++, więc po co o tym pisałeś? I napisz w kontekście nie-C++ co jest złego w iteratorach. Programując często ich używam i nigdy problemów nie zaobserwowałem.
11. A co miał znaczyć ten fragment:
No ale tego właśnie niestety uczy C++.
I znów z ciekawości: jakie są kruczki składniowe i wieloznaczności. Ja z kolei słyszałem (podkreślam to słyszałem, bo ja nie mam żadnych problemów), że kompatybilność z podstarzałym C powoduje jakieś problemy.

ODPOWIEDZ