VrînceanAlex.lüxor

[C] Tricky functions#1 ~ Citirea unui cstring de lungime nedeterminata.

1 post în acest topic

Algoritmul C:  Functia va citi din fisier(sau consola) pana cand va gasi un anumit caracter (stabilit de voi). Iar rezultatul va fi salvat intr-un char*.

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. char* readString(FILE* FilePointer, char EndCharacter)
  5. {
  6.     char *InputString, Character;
  7.     size_t Lenght = 0, Size = 10;
  8.     InputString = (char*)realloc(NULL, sizeof(char)*Size);
  9.     if (!InputString)
  10.         return NULL;
  11.     if (FilePointer == stdin)
  12.     {
  13.         InputString[Lenght] = fgetc(FilePointer);
  14.         if (InputString[Lenght] != '\n')
  15.             Lenght++;
  16.     }
  17.     while (EOF != (Character = fgetc(FilePointer)) && Character != EndCharacter)
  18.     {
  19.         InputString[Lenght++] = Character;
  20.         if (Lenght == Size)
  21.             InputString = (char*)realloc(InputString, sizeof(char)*(Size *= 2));
  22.         if (!InputString)
  23.             return NULL;
  24.     }
  25.     InputString[Lenght++] = '\0'
  26.     return (char*)realloc(InputString, sizeof(char)*Lenght);
  27. }

 

 

Ok, spre deosebire de ce am facut pana acum asta e super complex, ideea in algoritm e urmatoarea : 

- initializam un cstring (char*) in care vom salva stringul si un char care va citi din fisier caracter cu caracter + 2 variabile de tip size_t (size_t este defapt unsigned long int, pe scurt este un fel de long int care nu permite valori negative si de dimensiune dubla)

- alocam un spatiu dinamic (conform : http://en.cppreference.com/w/c/memory/realloc) realloc(NULL, ceva); este echivalent cu malloc(ceva);

De retinut : malloc/calloc/realloc - toate returneaza void*, asa ca trebuie sa convertim in tipul nostru : char*.

- la final verificam ca alocarea sa fie efectuata cu succes, altfel returnam NULL. (pointer inaccesibil, practic semnalam ca operatia a esuat).

- urmatorul pas este unul particular, in caz ca este introdus stdin ca si pointer de citire si caracterul enter : '\n' a fost introdus, poate aparea un bug, asa ca vom incerca sa-l remediem, mai pe scurt vom citi un caracter din consola iar daca acesta nu este '\n' il vom baga in stringul nostru.

- acum vine partea automata, vom citi de la tastatura pana cand gasim caracterul introdus de noi sau pana cand se va termia fisierul (EOF, care inseamna End of file), sau pana cand Size va si egal cu Lenght (adica pana cand numarul caracterelor introduse va fi egal cu numarul de caractere maxim introduse) in acest caz vom realoca pointerul, pentru a primi o dimensiune dubla. La fel, in cazul unui esec al realocarii vom returna NULL.

- spre final, pentru ca cstring-urile se termina cu caracterul null vom introduce caracterul '\0' la final.

- la final, vom realoca cstringul cu valorea lui Lenght, pentru a avea fix dimensiunea sigurului.

 

Exemplu de apelare a functiei :

  1. int main()
  2. {
  3.     FILE* FilePointer = fopen("file.txt", "r");
  4.     char* String1 = readString(stdin,'\n') // citeste din consola pana la primul newline
  5.     char* String2 = readString(FilePointer , EOF)// citeste din fisierul file.txt pana cand se va termina.
  6.  
  7.     // do things
  8.     free(String1);
  9.     free(String2);
  10.     fclose(FilePointer);
  11.     return 0;
  12. }

Evindet la final se vor elibera spatiile de memorie consumate.

Partajează acest post


Link spre post
Distribuie pe alte site-uri

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!


Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.


Autentifică-te acum