C99 - czy warto użyć PCRE

0

Jestem w trakcie pisania kodu w języku C99.

#define _WITH_GETLINE
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_KEY_SIZE 20
#define MAX_VALUE_SIZE 40

typedef struct alias {
  char key[MAX_KEY_SIZE];
  char value[MAX_VALUE_SIZE];
} alias;

alias read_alias(const char* str)
{
  alias tmp; 
  int i = 0;
  char* tok = NULL;
  char* pstr = strdup(str);
  while ( (tok = strtok(pstr, "=")) ) {
    if(i == 0) 
      strncpy(tmp.key, tok, MAX_KEY_SIZE);
    else {
      ++tok; // no need to copy '"'
      strncpy(tmp.value, tok, MAX_VALUE_SIZE);
      tmp.value [ strlen(tmp.value) - 2 ] = 0; // delete '"'
    }
    pstr = NULL; ++i;
  }
  free(pstr);
  
  return tmp;
}

void display_alias(alias** alias_array, int n)
{
  alias* a = *alias_array;
  for(int i = 0; i < n; ++i)
    printf("%s=\"%s\"\n", a[i].key, a[i].value);
}

int main()
{
  alias* alias_array = NULL;
  FILE* fp = NULL;
  
  if( (fp = fopen("alias.db", "r"))  == NULL ) {
    fprintf(stderr, "Cannot open alias file!\n");
    exit(1);
  }
  
  char* line = NULL; size_t size;
  int numberofaliases;
  
  for (numberofaliases = 0; getline(&line, &size, fp) > 0; ++numberofaliases) {     
      // check syntax of the line
      
      // read alias from file and adjust size of array
      alias_array = realloc(alias_array, sizeof(alias)*numberofaliases+sizeof(alias) );
      alias_array[numberofaliases] = read_alias(line);
  }
  printf("Number of aliases: %d\n", numberofaliases);

  display_alias(&alias_array, numberofaliases);

  fclose(fp);
  free(alias_array);
  
  return 0;
}

ls="ls -aF"
c="clear"
  1. Nie jestem pewien czy dobrze rezerwuje pamięć.
  2. Rozważam użycie wyrażeń regularnych do sprawdzania poprawności składni w pliku. Zastanawia mnie jednak czy jest to rozsądne rozwiązanie. Wyrażenie jest stosunkowo proste i możnaby napisać funkcje (chyba i tak będzie dłuższa niż wyrażenie regularne), która sobie poradzi bez dodatków. Jak w takiej sytuacji postępują typowi programiści C? PCRE to już będzie przesada?

Pozdrawiam,

0

Jestem w trakcie pisania kodu w języku C99.
Trochę to nieścisłe. Język nazywa się C, a jego aktualny standard to ISO/IEC 9899:1999, zatytułowany „Programming languages — C”, potocznie nazywany C99. Ostatnia poprawka standardu (oznaczona ISO/IEC 9899:TC3) miała miejsce w 2007 roku.
O tym, że nie jest to jakiś zupełnie nowy język świadczy fakt, że w dokumencie cały czas jest mowa o C (a nie C99), oraz zdanie

This second edition cancels and replaces the first edition, ISO/IEC 9899:1990

void display_alias(alias** alias_array, int n)
podwójny wskaźnik nie jest tu potrzebny.

char* line = NULL;
...
for (numberofaliases = 0; getline(&line, &size, fp) > 0; ++numberofaliases) {     
...
  }

nigdzie nie zwalniasz line które ci getline() zaalokowało.

alias_array = realloc(alias_array, sizeof(alias)*numberofaliases+sizeof(alias) );
to nie jest dobry pomysł, by realokować pamięć za każdym przebiegiem. jeśli linii w pliku będzie dużo, kod będzie powolny i będzie bardzo szatkował pamięć. chyba że realloc jest zoptymalizowany by nie kopiować pamięci za każdym razem. ale kto go tam wie…

0

Dzięki za uwagę. Użyłem podwójnego wskaźnika ponieważ wydaje mi się, że będzie to szybsze (nie będzie tworzona zmienna lokalna). Czy rzeczywiście ma to wpływ na szybkość? Rozumiem, że w przypadku modyfikacji nie obejdzie się bez podwójnego wskaźnika.

1 użytkowników online, w tym zalogowanych: 0, gości: 1