This is an old revision of the document!
Resposabili:
În urma parcurgerii acestui laborator studentul va fi capabil:
Un caracter se declară în C de forma: char a='a'
; Pentru initializarea lui, se observă că am pus un caracter între apostroafe.
Un şir de caractere presupune practic un vector de caractere. Cea mai simplă declaraţie fiind: char a[10]= “cuvant”
; Pentru iniţializarea unui şir de caractere, spre deosebire de un singur caracter am folosit ghilimelele.
Cum s-a prezentat anterior, o variabilă vector conţine adresa de început a vectorului(adresa primei componente a vectorului), şi de aceea este echivalentă cu un pointer la tipul elementelor din vector. Deci declaraţiile de mai jos vor declara fiecare cate un şir de caractere:
char a[5]; char *b="unsir"; char *c;
Diferenţa între ele este însa că primele două declaraţii vor aloca 5 pozitii în memorie, pe când ultima nu va aloca nici o zona de memorie, necesitând sa fie ulterior alocată, folosind funcţiile de alocare dinamică (malloc(), calloc(), realloc()
), prezentate în laboratorul anterior. Un mic exemplu de citire a unui şir, caracter cu caracter pana la 0:
#include <stdio.h> #include <string.h> #define N 30 int main () { char str[N], c; int n = 0; do { scanf("%c", &c) if (c == '0') { break; } str[n++] = c; } while(1); str[n] = '\0'; printf("%s", str); return 0; }
Pentru citirea si afisarea unui şir de caractere se poate folosi flagul 's' la citirea cu scanf
sau afişarea cu printf
. Deasemenea biblioteca stdio.h
defineşte funcţiile gets()
şi puts()
pentru lucrul cu şiruri de caractere.
gets(zona)
-– citeşte de la terminalul standard un şir de caractere terminat cu linie noua (enter).puts(zona)
– afişeaza la terminalul standard şirul de caractere din zona data ca parametru, până la caracterul terminator de şir(\0), care va fi înlocuit prin caracterul linie noua.
gets()
va citi de la tastatura câte caractere sunt introduse, chiar daca şirul declarat are o lungime mai mică. Presupunem un şir declarat: char a[]=”unsir”
, care va avea deci 5 caractere. Citind un şir de lungime mai mare ca 5 de la tastatura, în şirul a, la afişare vom vedea ca s-a reţinut tot sirul!(nu doar primele 5 caractere). Nimic deosebit până acum. Dar dacă luăm în considerare că citirea caracterelor auxiliare se face în continuare în zona de memorie, ne punem problema ce se va suprascrie?!
Raspunsul este: nu se ştie… poate nimic important pentru programul nostru, poate ceva ce il va bloca sau duce la obţinerea de date eronate.
Pentru a evita aceasta se recomandă utilizarea fgets()
.
fgets(zona, lung_zona, stdin)
-– citeşte de la stdin
un şir de caractere terminat printr-o linie nouă dacă lungimea lui este mai mică decat lung_zona
sau primele lung_zona
caractere în caz contrar. Parametrii sunt: zona de memorie, lungimea maxima admisă a şirului, şi terminalul standard de intrare. În cazul în care şirul dorit are lungime mai mică decât cea maximă, înaintea terminatorului de şir (\0), în zona de memorie va fi reţinut şi enter-ul dat(\n).Pentru manipularea şirurilor de caractere în limbajul C se folosesc funcţii declarate în fişierul <string.h>. Vom încerca să le detaliem putin pe cele mai des folosite:
size_t strlen(const char *str);
Returneaza lungimea unui şir dat ca parametru. (numarul de caractere până la întalnirea terminatorului de şir:\0)
Exemplu:
#include <stdio.h> #include <string.h> #define N 256 int main () { char text[N]; printf("Introduceti un text: "); gets(text); printf("Textul are %u caractere.\n", strlen(text)); return 0; }
Iesire:
Introduceti un text: just testing Textul are 12 caractere.
void* memset(void *ptr, int val, size_t num);
În zona de memorie dată de pointerul ptr, sunt setate primele num poziţii la valoarea dată de val. Funcţia returnează şirul ptr.
Exemplu:
#include <stdio.h> #include <string.h> int main () { char str[] = "nu prea vreau vacanta!"; memset(str, '-', 7); puts(str); return 0; }
Iesire:
------- vreau vacanta!
void* memmove(void *destination, const void *source, size_t num);
Copiază un număr de num caractere de la sursă, la zona de memorie indicată de destinaţie. Copierea are loc ca şi cum ar exista un buffer intermediar, deci sursa si destinatia se pot suprapune. Funcţia nu verifică terminatorul de şir la sursă, copiază mereu num bytes, deci pentru a evita depăsirea trebuie ca dimensiunea sursei sa fie mai mare ca num. Funcţia returnează destinaţia.
Exemplu:
#include <stdio.h> #include <string.h> int main () { char str[] = "memmove can be very useful......"; memmove(str + 20, str + 15, 11); puts(str); return 0; }
Iesire:
memmove can be very very useful.
void* memcpy(void *destination, const void *source, size_t num);
Copiază un număr de num caractere din şirul sursă in şirul destinaţie. Funcţia returnează şirul destinaţie.
Exemplu:
#include <stdio.h> #include <string.h> #define N 40 int main () { char str1[] = "Exemplu"; char str2[N]; char str3[N]; memcpy(str2, str1, strlen(str1) + 1); memcpy(str3, "un sir", 7); printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3); return 0; }
Iesire:
str1: Exemplu str2: Exemplu str3: un sir
char* strcpy(char *destination, const char *source);
Copiază şirul sursă in şirul destinaţie. Şirul destinaţie va fi suprascris. Funcţia asigură plasarea terminatorului de şir în şirul destinaţie după copiere. Funcţia returneaza şirul destinaţie.
char* strncpy(char *destination, const char *source, size_t num);
Asemeni cu strcpy()
, dar in loc de a fi copiată toata sursa sunt copiate doar primele num caractere.
Exemplu:
#include <stdio.h> #include <string.h> #define N 40 int main () { char str1[] = "Exemplu"; char str2[N]; char str3[N]; strcpy(str2, str1); strncpy(str3, "un sir", 2); printf("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3); return 0; }
Iesire:
str1: Exemplu str2: Exemplu str3: un
char* strcat(char *destination, const char *source);
Concatenenaza şirul sursă la şirul destinaţie. Funcţia returnează şirul destinaţie.
char* strncat(char *destination, const char *source, size_t num);
Asemeni cu strcat()
, dar în loc de a fi concatenată toată sursa sunt concatenate doar primele num caractere.
Exemplu:
#include <stdio.h> #include <string.h> #define N 80 int main () { char str[N]; strcpy(str, "ana "); strcat(str, "are "); strcat(str, "mere "); puts(str); strncat(str, "si pere si prune", 7); puts(str); return 0; }
Iesire:
ana are mere ana are mere si pere
int strcmp(const char *str1, const char *str2);
Compară şirul str1 cu şirul str2, verificându-le caracter cu caracter. Valoarea returnată este 0 daca cele şiruri sunt identice, mai mare ca 0 daca str1 este “mai mare”(alfabetic) şi mai mic ca 0 altfel.
Exemplu:
#include <stdio.h> #include <string.h> #define N 80 int main () { char cuv[] = "rosu"; char cuv_citit[N]; do { printf ("Ghiceste culoarea..."); gets(cuv_citit); } while (strcmp(cuv,cuv_citit) != 0); puts("OK"); return 0; }
char* strchr(const char *str, int character);
Caută caracterul character în şirul str şi returnează un pointer la prima sa apariţie.
char* strrchr(const char *str, int character);
Caută caracterul character în şirul str şi returnează un pointer la ultima sa apariţie.
char* strstr(const char *str1, const char *str2);
Caută şirul str2 în şirul str1 şi returnează un pointer la prima sa apariţie, sau NULL
dacă nu a fost găsit.
char* strdup(const char *str);
Realizează un duplicat al şirului str, pe care îl şi returnează.
Exemplu:
#include <stdio.h> #include <string.h> #define N 80 int main () { char str[N], *d; do { if (gets(str) == 0) { break; } d = strdup(str); puts(d); } while (1); return 0; }
char* strtok(char *str, const char *delimitators);
Funcţia are rolul de a împarţi şirul str în tokens(subşiruri separate de orice caracter aflat în lista de delimitatori), prin apelarea ei succesivă.
La primul apel, parametrul str trebuie sa fie un şir de caractere, ce urmează a fi împartit. Apelurile urmatoare, vor avea în loc de str, NULL
conţinuând împarţirea aceluiaşi şir.
Funcţia va returna la fiecare apel un token(un subsir), ignorând caracterele cu rol de separator aflate în şirul de delimitatori. O dată terminat şirul, funcţia va returna NULL
.
<string.h>
nu permite folosirea strtok()
în paralel pe mai mult de un şir.
Exemplu:
#include <stdio.h> #include <string.h> int main () { char str[] = "- Uite, asta e un sir."; char *p; p = strtok(str, " ,.-"); /* separa sirul in "tokeni" si afiseaza-i pe linii separate. */ while (p != NULL) { printf("%s\n", p); p = strtok(NULL, " ,.-"); } return 0; }
Iesire:
Uite asta e un sir
void ordCresc(char *vectorschar[], int n);
care să ordoneze cuvintele crescător<string.h>
înlocuiţi într-un text dat o secventă de caractere cu altă secvenţă de caractere, date la intrare.