Przejdź do zawartości

BasicC/Napisy

Z Wikibooks, biblioteki wolnych podręczników.
 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)

[edytuj]

Definicja: 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)

[edytuj]

Zwykle 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)

[edytuj]

Dział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)

[edytuj]

Zamienia 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)

[edytuj]

Definicja: 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)

[edytuj]

Definicja: strlen(A)
Zwraca długość ciągu znaków.

Len$(A)

[edytuj]

Definicja: (unsigned char)A[STRLEN]
Szybsza wersja Len dla A typu $.

LenChr(S,d,n)

[edytuj]

Podaje 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)

[edytuj]

Podaje 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)

[edytuj]

Definicja: 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)

[edytuj]

Definicja: {memmove(A,B,B[STRLEN]+1);A[STRLEN]=B[STRLEN];}
Zwykle szybsze Let dla B zgodnego z $.

LetMid(T,S,a,n)

[edytuj]

Definicja: {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)

[edytuj]

LetMid dla S zgodnego z $. Obsługuje DEBUG.

UWAGA ! Brak kontroli przekroczenia tablicy !

MemSet(A,N,B)

[edytuj]

Definicja: 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)

[edytuj]

Funkcja 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)

[edytuj]

Funkcja 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)

[edytuj]

Definicja: 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)

[edytuj]

Definicja: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)

[edytuj]

Definicja: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)

[edytuj]

Definicja:S[STRLEN]=snprintf(S,STRLEN,"%.16lG",(double)D);
J. w., ale S będzie zgodne z $. Obsługuje DEBUG.

Str$(D)

[edytuj]

Funkcja 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)

[edytuj]

Zamienia litery w napisie S na małe. Działa tylko na standardowych znakach ASCII 65-90.

Upper(S)

[edytuj]

Zamienia 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