BasicC/Napisy
Nieuważne korzystanie ze standardowych napisów w C może powodować krytyczne błędy. BasicC oferuje funkcje operowania na łańcuchach w łatwiejszy i bezpieczniejszy sposób.
#define STRLEN 255
Zdefiniowana jest stała STRLEN o domyślniej wartości 255 oznaczająca maksymalną długość napisów typu STRING (bez znaku końca '\0'). Nie mylić z funkcją strlen, która zwraca długość danego łańcucha. Odpowiednie zmniejszenie tej wartości przyśpiesza niektóre operacje na napisach.
Ograniczenie długości napisów nie jest restrykcyjne w wersji WWW, ale zalecane ze względu na kompatybilność.
typedef char STRING[STRLEN+1];
Zdefiniowany jest typ danych STRING oznaczający łańcuch maks. długości STRLEN.
STRING STRING$;
Zdefiniowana jest zmienna pomocnicza STRING$ typu STRING używana w niektórych operacjach na łańcuchach.
Od wersji 1.23 wprowadzono komendy operujące na rozszerzonym typie STRING zawierającym informację o faktycznej długości napisu przechowywanego w zmiennej (nie dotyczy to wersji WWW). Ma to na celu przyspieszenie operacji na tekstach przy dużej wartości STRLEN. Nowy typ nie jest deklarowany, korzysta się z typu STRING, należy ręcznie wpisać długość napisu w ostatniej komórce tablicy (o indeksie STRLEN) reprezentującej łańcuch. Komendy oznaczone znakiem $, operujące na tych zmiennych, robią to automatycznie. Ponieważ zajmujemy dodatkowo komórkę - taki napis może mieć maksymalną długość STRLEN-1, STRLEN nie może być większe niż 256. W związku z tym komendy BasicC mogą operować na 3 rodzajach łańcuchów znaków: char* - standardowy dla C (dowolna tablica znaków); STRING - tablica znaków długości STRLEN+1; STRING z informacją o długości napisu w ostatniej komórce, który dalej będzie nazywany $. Typy te są zgodne wstecznie. Ogólnie komendy dające napisy zgodne z $ zakończone są znakiem $.
Większość komend operujących na łańcuchach wymaga biblioteki string.h, jest ona domyślnie załączona w BasicC.
Add(A,B)
edytujDefinicja: strncat(A,B,STRLEN-strlen(A));
Komenda kopiuje łańcuch B na koniec łańcucha (od znaku '\0') w zmiennej A wraz ze znakiem '\0', maksymalnie STRLEN-Len(A) znaków. W wyniku czego łańcuch A będzie składał się ze wcześniejszego łańcucha A połączonego z B.
Formuła typu "tekst"+"tekst2" dopuszczalna jest tylko w C++ dla obiektów typu string, który jest czymś innym niż STRING z BasicC.
Add$(A,B)
edytujZwykle szybszy odpowiednik komendy Add, dla zmiennych $. Wykorzystuje informacje o długości napisów zapisane w komórkach A[STRLEN] i B[STRLEN], w wynikowej tablicy A również zapisana zostaje informacja o długości połączonego łańcucha. Obsługuje DEBUG.
Cat$(A,B)
edytujDziała podobnie do komendy Add, lecz nie modyfikuje zmiennej A, wynik zapisuje do zmiennej STRING$, zwraca wskaźnik do tej zmiennej. Działa wolniej od komendy Add, operuje na wszystkich 3 typach zmiennych o długości do STRLEN-1, wynik jest zgodny z $. Obsługuje DEBUG.
Chr$(C)
edytujZamienia znak na łańcuch. Funkcja zwraca napis zgodny z $ złożony ze znaku C (+znak końca napisu '\0'), napis ten jest tworzony od pozycji STRLEN-2 tablicy STRING$, więc jeśli zawierała napis krótszy niż STRLEN-2 - pozostanie on niezmieniony, utracona będzie jedynie ew. informacja o jego długości.
Cmp(A,B)
edytujDefinicja: strcmp(A,B)
Porównuje łańcuch A z B, zwraca 0, gdy są takie same, >0 gdy A>B, <0 gdy A<B.
Len(A)
edytujDefinicja: strlen(A)
Zwraca długość ciągu znaków.
Len$(A)
edytujDefinicja: (unsigned char)A[STRLEN]
Szybsza wersja Len dla A typu $.
LenChr(S,d,n)
edytujPodaje ilość znaków w ciągu S przechodząc przez n liter (lub do końca ciągu) poczynając od pozycji d. Funkcja uwzględnia fakt, że niektóre litery (np. polskie diakrytyczne) złożone są z kilku znaków (bajtów) o wartości spoza zakresu ASCII 0-127 i przyjmuje, że są to 2 znaki. NIE OBSŁUGUJE KODOWANIA Z >2 ZNAKAMI NA LITERĘ ! d jest wskaźnikiem tablicy znaków, nie jest numerem litery. n jest ilością liter i może być ujemne, wtedy przeszukiwanie przebiega w tył. Jeśli przeszukiwanie rozpoczyna się na literze 2-bajtowej - d musi wskazywać na pierwszy znak tej litery, a przy przeszukiwaniu w tył - na drugi, czyli pierwszy od końca.
LenUTF(S,d,k)
edytujPodaje ilość liter w ciągu S licząc od znaku na pozycji d do znaku k, k>=d>0. Uwzględnia, że litera może się składać z 2 znaków spoza ASCII 0-127.
Let(A,B)
edytujDefinicja: strncpy(A,B,STRLEN+1);
Kopiuje łańcuch B do zmiennej A. Podobny efekt i, być może, większą szybkość daje {A[0]='\0';strncat(A,B,STRLEN);}
, jednak wtedy Let(A,A) zwracała by łańcuch pusty.
W języku C, więc również w Basic C, wyrażenie typu zmienna="tekst" jest dopuszczalne tylko przy deklaracji zmiennej, w dalszych częściach programu jest to możliwe tylko w C++ przy użyciu klasy string, w C należy używać komend kopiowania, takich jak Let.
Let$(A,B)
edytujDefinicja: {memmove(A,B,B[STRLEN]+1);A[STRLEN]=B[STRLEN];}
Zwykle szybsze Let dla B zgodnego z $.
LetMid(T,S,a,n)
edytujDefinicja: {memmove(T,&S[a],n);T[n]=0;}
Kopiuje do zmiennej T n znaków łańcucha S od znaku na pozycji a, na końcu dodaje znak '\0'. Pozycje numerowane są od 0. Obsługuje DEBUG.
UWAGA ! Brak kontroli przekroczenia tablicy ! By uniknąć przekroczenia można jako n podać STRLEN lub Min(n,STRLEN).
LetMid$(T,S,a,n)
edytujLetMid dla S zgodnego z $. Obsługuje DEBUG.
UWAGA ! Brak kontroli przekroczenia tablicy !
MemSet(A,N,B)
edytujDefinicja: memset(A,B,N);
Wstawia N bajtów B do pamięci wskazywanej przez A. A może być zmienną łańcuchową, a B znakiem w apostrofach, jednak nie ma kontroli przepełnienia i należy pamiętać, że łańcuch powinien być zakończony 0.
Mid$(S,a,n)
edytujFunkcja działająca jak LetMid(STRING$,S,a,n), ale dodatkowo zwraca wskaźnik do zmiennej STRING$ zgodnej z $, czyli wynikowy napis. Działa na wszystkich 3 typach. Obsługuje DEBUG.
UWAGA ! Brak kontroli przekroczenia tablicy !
Mk$(char*S)
edytujFunkcja zwraca łańcuch tekstowy zgodny z $ utworzony z łańcucha S. Główne zastosowanie to ręczne wprowadzanie tekstu jako argumentu funkcji wymagającej łańcucha zgodnego z $. Działa dość wolno i wykorzystuje zmienną STRING$, dlatego np. zamiast Let$(a,Mk$("tekst")) lepiej użyć Let(a,"tekst") String$(a).
Val(S)
edytujDefinicja: strtod(S,NULL)
Zwraca wartość liczbową skonwertowaną z napisu S. Jeśli konwersja jest niemozliwa - zwraca 0. Funkcja nie wymaga biblioteki string.h, wymaga stdlib.h domyślnie załączonej w BasicC.
String$(S)
edytujDefinicja:S[STRLEN]=strlen(S);
Czyni łańcuch S zgodnym z $, czyli zapisuje w ostatniej komórce jego długość. Służy np. do inicjacji zmiennych zgodnych z $.
LetStr(S,D)
edytujDefinicja:snprintf(S, STRLEN+1, "%.16lG", (double)D);
Komenda powoduje konwersję liczby D na tekst, który jest zapisywany w podanej zmiennej S. Ilość cyfr jest ograniczona do 16.
LetStr$(S,D)
edytujDefinicja:S[STRLEN]=snprintf(S,STRLEN,"%.16lG",(double)D);
J. w., ale S będzie zgodne z $. Obsługuje DEBUG.
Str$(D)
edytujFunkcja działająca jak LetStr$(STRING$,D), zwraca wskaźnik do zmiennej STRING$, wynikowy napis zgodny z $. Obsługuje DEBUG.
3 powyższe komendy nie wymaga biblioteki string.h, wymagają stdio.h domyślnie załączonej w BasicC.
Lower(S)
edytujZamienia litery w napisie S na małe. Działa tylko na standardowych znakach ASCII 65-90.
Upper(S)
edytujZamienia litery w napisie S na duże. Działa tylko na standardowych znakach ASCII 97-122.
Komendy Lower i Upper nie wymagają dodatkowej biblioteki.
UWAGA ! Nie zaleca się jednoczesnego używania wielu komend wykorzystujących tą samą zmienną STRING$, może to dawać nieoczekiwane rezultaty.
Przykład:
#define DEBUG 1
#define STRLEN 33
#include "Basic.h"
STRING a$="napis1",b$="napis2",c="napis3";
MAIN
String$(a$) String$(b$)
Print$ Str$(123) NL
Print$ a$ $ "+" $ b$ $ "=" );
Add$(a$,b$)
Print$ a$ _ Len$(a$) NL
Print$ Cat$(a$,b$) $ a$ NL
Print Cmp(a$,b$) NL
Print Len(c) NL
Let$(a$,b$)
Print$ a$ _ Len$(a$) NL
Print$ Mid$(c,1,30) NL
Print Val("12345ABX") NL
char *a="łódź";
Print LenUTF(a,0,STRLEN) NL
Print LenUTF(a,2,STRLEN) NL
Print LenChr(a,2,STRLEN) NL
Print LenChr(a,1,-5) NL
ENDMAIN