Jump to content
Sign in to follow this  
lüxor - High all the time.

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

Recommended Posts

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.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...