CYFROWY BARON • PROGRAMOWANIE • Zobacz wątek - Jak napisać funkcję

Jak napisać funkcję

dział ogólny

Jak napisać funkcję

Nowy postprzez scrobik » poniedziałek, 20 września 2010, 15:46

Mam problem a mianowicie nie wiem jak napisać funkję która pobierała by wskaźnik do tablicy znaków char i zwracała by wartość true jeżeli znajdowały by się tam znaki( same cyfry i ewentualnie przecinek ) BEZ LITER, a wartość false, jeżeli wystąpiła by tam jakakolwiek liter. Może już ktoś ma gotową taką funkcję. Proszę o pomoc i pozdrawiam.
Avatar użytkownika
scrobik
Bladawiec
Bladawiec
 
Posty: 6
Dołączył(a): wtorek, 8 czerwca 2010, 21:26
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder Enterprise Suite Ver. 6.0
Gadu Gadu: 5744883
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez polymorphism » wtorek, 21 września 2010, 09:54

Jest funkcja isalpha, którą możesz sprawdzić, czy dany znak jest literą. Co do reszty... może pokaż, co sam spłodziłeś.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez Cyfrowy Baron » wtorek, 21 września 2010, 10:27

Nie natknąłem się wcześniej na tą funkcję i kombinowałem z funkcją strchr, ale to wymagało utworzenia dodatkowej tablicy zawierającej wszystkie znaki nie będące literami. Funkcja isalpha znacznie to upraszcza.

KOD cpp:     UKRYJ  
bool __fastcall IsLetter(char lpSet[])
{
 for(int x = 0; x < strlen(lpSet); x++)
 {
  if( isalpha( lpSet[x] ) )
  {
   return false;
  }
 }
 return true;
}
// TESTOWANIE
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 if( IsLetter(":12345aAbBcdefgf") ) ShowMessage("TRUE");
 else ShowMessage("FALSE");
}




Co się tyczy mojego wcześniejszego problemu (post już usunąłem) z funkcją sizeof do pobierania długości tablicy char, to się trochę pogubiłem. Do pobierania długości tablicy char najprościej jest użyć funkcji strlen.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez polymorphism » wtorek, 21 września 2010, 11:10

Trzy sprawy do Twojego kodu:
  • strlen w pętli - ilość iteracji to N2. Zasadniczo ta funkcja nie jest tutaj potrzebna.
  • nie wiem, jak w CB to wygląda, ale w VC muszę rzutować kod znaku na typ unsigned (chodzi o wersję z cliba), w przeciwnym razie mam asercję dla znaków z kodami powyżej 127.
  • zapomniałeś o ustawieniach lokalizacyjnych, a prościej - kodowaniu. Być może w CB domyślnie jest ustawione na systemowe, ale VC nie jest, dlatego warto o tym pamiętać.

KOD cpp:     UKRYJ  
bool IsNonAlphaString(const char *p)
{
        while(*p && !isalpha((unsigned char)*p))++p;
        return *p == 0;
}

// wywołanie
setlocale(LC_CTYPE,".ACP");

cout << IsNonAlphaString("666") << '\n';
cout << IsNonAlphaString("ęąźćż") << '\n';
 


Tu wersja C++'owa. Zaletą jest to, że można ustawić kodowanie na użytek tylko tej funkcji, lokalnie:
KOD cpp:     UKRYJ  
#include <locale>

...

bool IsNonAlphaString(const char *p,const locale &loc)
{
        while(*p && !isalpha(*p,loc))++p;
        return *p == 0;
}

// wywołanie
cout << IsNonAlphaString("666",locale(locale(),".ACP",locale::ctype)) << '\n';
cout << IsNonAlphaString("ęąźćż",locale(locale(),".ACP",locale::ctype)) << '\n';
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez Cyfrowy Baron » wtorek, 21 września 2010, 12:15

nie wiem, jak w CB to wygląda, ale w VC muszę rzutować kod znaku na typ unsigned (chodzi o wersję z cliba), w przeciwnym razie mam asercję dla znaków z kodami powyżej 127.


W C++Builder działa, ale tylko ze znakami języka angielskiego. By zadziałało z polskimi znakami diakrytycznymi muszę użyć zarówno rzutowania jak i ustwić lokalizację.



Przyznaję, że nie znałem tych funkcji, gdyż nigdy wcześniej nie potrzebowałem ich stosować, a w plik pomocy też się nie wczytywałem. Sądziłem, że funckja, sama wszystko wykrywa, czyli jest bardziej uniwersalna, niż to się okazało.



Tutaj lista innych podobnych funkcji, które mogą się przydać:

int isalnum(int c);
int isalpha(int c);
int isascii(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez polymorphism » wtorek, 21 września 2010, 12:56

Tak sobie przeczytałem jeszcze raz post scrobika i chyba trochę się z tą isalpha rozpędziliśmy, bo chodzi o "same cyfry i ewentualnie przecinek". Zatem strchr wystarczy do tego zadania (można użyć isdigit, jeśli przewidujemy cyfry w innych wariantach etnicznych niż europejskim, np. arabskim: ٠١٢٣٤٥٦٧٨٩ (CP1256)).
Ostatnio edytowano wtorek, 21 września 2010, 14:11 przez polymorphism, łącznie edytowano 1 raz
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2156
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 200
System operacyjny: Windows 8.1
Windows 10
Linux Mint 21.1
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez Cyfrowy Baron » wtorek, 21 września 2010, 13:00

Początkowo opracowałem kod ze strchr, ale gdy zaproponowałeś isalpha, to wydał mi się lepszy. Wydaje mi się, że najpierw scrobik powinien się dokładniej dookreślić, czy chodzi o cyfry + przecinek vs. litery, czy też o litery vs. cała reszta znaków.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez scrobik » wtorek, 21 września 2010, 18:01

Sprawa wygląda tak, że mam zmienną char str1 zapisuje się w StrinGrid bez probelmu i chce ją przekonwertować do Float i wyświetlić na wykresie jak to przedstawia poniższy kod, ale problem jest w tym że w zmiennej str1 która powinna mieć format #,### pojawiają się litery i tu mi wyżuca błąd, Mam poniżej zrobiony wyjątek w razie wystąpienia innego typu zmiennj niż float ale to też nie działa. Co zrobić? pozdrawiam i dzięki za pomoc

KOD cpp:     UKRYJ  
 //======tabelka===
     str1 = strtok(NULL, ":");
     StringGrid1->Cells[5][1] = str1;
     //====koniec tabelka

     //======wykres
     temp_float = -1.0;
     try{
        temp_float = StrToFloat(str1);
     }catch(exception &e){
       // cout << "Blad konwersji"<<"\n";//mozna message boxa
        temp_float = -1.0;
     }

     if(temp_float >= 0 )  {
        Wykres3->Add(temp_float);
     }
Avatar użytkownika
scrobik
Bladawiec
Bladawiec
 
Posty: 6
Dołączył(a): wtorek, 8 czerwca 2010, 21:26
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder Enterprise Suite Ver. 6.0
Gadu Gadu: 5744883
    Windows XPOpera

Re: Jak napisać funkcję

Nowy postprzez Cyfrowy Baron » wtorek, 21 września 2010, 18:14

Użyj po prostu funkcji StrToFloatDef(UnicodeString s, long double default):

KOD cpp:     UKRYJ  
String tekst = "jakiś tekst niekoniecznie liczba";
float x = StrToFloatDef(tekst, -1.0);/* jeżeli nie można dokonać konwersji zwrócona zostanie wartość domyślna, tutaj -1*/


Jak widzę, nie było wogóle potrzeby takiego kombinowania z rozpoznawaniem tekstu i liczb. Gdybyś od razu napisał o co Tobie chodzi, to nie tracilibyśmy czasu, na wymyślanie funkcji, która tutaj nie ma po prostu zastosowania.

Dobrze byłoby ustalić jaki znak ma być używany jako separator dziesiętny, w przeciwnym razie program będzie używał separatora dziesiętnego zdefiniowanego w systemie, a te mogą być różne u różnych użytkowników. Jeżeli ustalisz, że separatorem ma być przecinek, to program zignoruje ustawienia systemowe i zawsze będzie szukał przecinka:
KOD cpp:     UKRYJ  
 TFormatSettings fs;
 GetLocaleFormatSettings(0, fs);
 fs.DecimalSeparator = ','; // ustawiłem przecinek jako separator dziesiętny.
 float x = StrToFloatDef(tekst, -1, fs);


Jeżeli spodziewasz się, że liczba może występować z różnym separatorem, raz przecinek, raz kropka, a chcesz by zawsze traktować separator jako przecinek, to możesz wymusić w programie zamianę kropki na przecinek. Zamiana zostanie dokonana tylko wtedy, gdy tekst będzie zawierał kropkę:
KOD cpp:     UKRYJ  
 String tekst = "10.2";
 tekst = StringReplace(tekst, ".", ",", TReplaceFlags() << rfReplaceAll);

 TFormatSettings fs;
 GetLocaleFormatSettings(0, fs);
 fs.DecimalSeparator = ',';

 float x = StrToFloatDef(tekst, -1, fs);


Z tego co pamiętam to w starszych wersjach środowiska C++Builder chyba nie występuje funkcja StrToFloatDef, pewien nie jestem. Jeżeli korzystasz ze starszej wersji środowiska i nie masz tej funkcji, to możesz użyć oczywiście metody try catch, ale trochę inaczej niż to robiłeś:

KOD cpp:     UKRYJ  
 String tekst = "10.2a";
 tekst = StringReplace(tekst, ".", ",", TReplaceFlags() << rfReplaceAll);

 TFormatSettings fs;
 GetLocaleFormatSettings(0, fs);
 fs.DecimalSeparator = ',';

 float x;
 try
 {
   x = StrToFloat(tekst, fs);
 }catch(...){ x = -1; }


Jeżeli odpalisz program przez środowisko to program zwróci wyjątek lub nie w zależności jak masz ustawione w swoim środowisku komunikaty. Program uruchomiony poza środowiskiem nie będzie już wyrzucał ostrzeżenia. Jeżeli nie chcesz otrzymywać takich komunikatów podczas testowania programu to możesz go sobie wyłączyć, w menu Tools -> Options - sekcja: Debugger Options -> Embarcadero Debuggers (nazwa zależy od wersji śr.) -> Language Exceptions - do sekcji Exception type to ignore dodaj wpis: EConvertError i zaznacz go ptaszkiem. Program podczas testowania przestanie rzucać takimi błędami. Gdy odznaczysz ptaszka komunikaty z ostrzeżeniami znów będą się pojawiać.

Uzupełnij profil by było widać z jakiej wersji środowiska korzystasz.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
Podziękował : 12
Otrzymał podziękowań: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    Windows XPFirefox

Re: Jak napisać funkcję

Nowy postprzez scrobik » czwartek, 23 września 2010, 20:26

Dziękuję za obszerne wyjaśnienie, teraz już wszystko śmiga i czegoś nowego się nauczyłem. Pozdrawiam :geek:
Avatar użytkownika
scrobik
Bladawiec
Bladawiec
 
Posty: 6
Dołączył(a): wtorek, 8 czerwca 2010, 21:26
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows XP Pro SP2
Kompilator: C++ Builder Enterprise Suite Ver. 6.0
Gadu Gadu: 5744883
    Windows XPOpera


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Ogólne problemy z programowaniem

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 7 gości

cron