Struktura do funkcji

0

Wiem ze takie tematy byly ale ja probowalem niektorych rozwiazan z nich i nic, nie wiem do konca jak to przekazac, kod wyglada tak:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<curl/curl.h>
#include<stdbool.h>

struct receiveData{
  char *memory;
  size_t size;
};

static char errorBuffer[CURL_ERROR_SIZE];
char *receiveInput();
static bool init(CURL *conn, char *url, struct receiveData rec);
static int writer(char *data, size_t size, size_t nmemb, void *userp);

int main(int argc, char *argv[]){
  CURL *conn = NULL;
  CURLcode code;
  char buffer[100];
  struct receiveData recDat;
  
  if (argc != 3 || (strcmp(argv[1], "pl") == 0 && strcmp(argv[1], "en") == 0)){
    fprintf(stderr, "Usage: %s pl/en <url>\n", argv[0]);
    
    exit(EXIT_FAILURE);
  }

  if(strcmp(argv[1], "pl") == 0)
    sprintf(buffer, "http://translatica.pl//translate.php?direction=plen&source=%s", argv[2]);
  if(strcmp(argv[1], "en") == 0)
    sprintf(buffer, "http://translatica.pl//translate.php?direction=enpl&source=%s", argv[2]);
  
  curl_global_init(CURL_GLOBAL_DEFAULT);
  printf("%s", buffer);
   
  if (!init(conn, buffer, recDat)){
    fprintf(stderr, "Connection initializion failed\n");
      
    exit(EXIT_FAILURE);
  }
  
  code = curl_easy_perform(conn);
  curl_easy_cleanup(conn);
 
  if(code != CURLE_OK){
      fprintf(stderr, "Failed to get '%s' [%s]\n", argv[2], errorBuffer);
 
      exit(EXIT_FAILURE);
    }

    return 0;
}

static bool init(CURL *conn, char *url, struct receiveData rec){
  CURLcode code;

  conn = curl_easy_init();
  if(conn == NULL){
    fprintf(stderr, "Failed to create CURL connection\n");
 
    exit(EXIT_FAILURE);
  }
  
  code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set error buffer [%d]\n", code);
 
    return false;
  }
 
  code = curl_easy_setopt(conn, CURLOPT_URL, url);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
 
    return false;
  }
 
  code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
  if (code != CURLE_OK){
    fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
 
    return false;
  }
  
  code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
 
    return false;
  }
  
  code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, (void *)&rec);
  if (code != CURLE_OK){
    fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
 
    return false;
    }
  
  return true;
}

static int writer(char *contents, size_t size, size_t nmemb, void *userp){
  size_t realsize = size * nmemb;
  struct receiveData *rec = (struct receiveData *)userp;

  rec->memory = realloc(rec->memory,rec->size + realsize + 1);
  if(rec->memory == NULL){
    printf("not enough memory (realloc returned NULL)\n");

    return 0;
  }

  memcpy(&(rec->memory[rec->size]), contents, realsize);
  rec->size += realsize;
  rec->memory[rec->size] = 0;
  
  return realsize;
}

chce przekazac strukture "receiveData" i otrzymac ja zapisana z powrotem w main.

1

Nie znam curla, ale wydaje mi się, że nie ma sposobu na otrzymanie wyniku funkcji czytającej. Zamiast tego przekaż po prostu receiveData przez wskaźnik, zamiast je kopiować. W ten sposób wszystkie zmiany będą widoczne również w oryginale.

Btw: nigdzie nie inicjalizujesz receiveData->memory, więc pierwsze wywołanie realloca może Cię rozwalić (UB).

1

http://format.krzaq.cc/ styl file. 2 spacje to za mało na wcięcie.

Przekazywanie parametru przez wartość i referencję - patrz na przekazywanie przez wskaźnik

0

przekazalem tak jak bylo to tam napisane twonek, oraz zaalokowalem miejsce, teraz wyglada to tak ale dalej jest to samo

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<curl/curl.h>
#include<stdbool.h>

struct receiveData{
  char *memory;
  size_t size;
};

static char errorBuffer[CURL_ERROR_SIZE];
char *receiveInput();
static bool init(CURL *conn, char *url, struct receiveData *rec);
static int writer(char *data, size_t size, size_t nmemb, void *userp);

int main(int argc, char *argv[]){
  CURL *conn = NULL;
  CURLcode code;
  char buffer[100];
  struct receiveData recDat;

  recDat.memory = malloc(1);
  recDat.size = 0;
  
  if (argc != 3 || (strcmp(argv[1], "pl") == 0 && strcmp(argv[1], "en") == 0)){
    fprintf(stderr, "Usage: %s pl/en <url>\n", argv[0]);
    
    exit(EXIT_FAILURE);
  }

  if(strcmp(argv[1], "pl") == 0)
    sprintf(buffer, "http://translatica.pl//translate.php?direction=plen&source=%s", argv[2]);
  if(strcmp(argv[1], "en") == 0)
    sprintf(buffer, "http://translatica.pl//translate.php?direction=enpl&source=%s", argv[2]);
  
  curl_global_init(CURL_GLOBAL_DEFAULT);
   
  if (!init(conn, buffer, &recDat)){
    fprintf(stderr, "Connection initializion failed\n");
      
    exit(EXIT_FAILURE);
  }
  
  code = curl_easy_perform(conn);
  curl_easy_cleanup(conn);
 
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to get '%s' [%s]\n", argv[2], errorBuffer);
 
    exit(EXIT_FAILURE);
  }

  return 0;
}

static bool init(CURL *conn, char *url, struct receiveData *rec){
  CURLcode code;

  conn = curl_easy_init();
  if(conn == NULL){
    fprintf(stderr, "Failed to create CURL connection\n");
 
    exit(EXIT_FAILURE);
  }
  
  code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set error buffer [%d]\n", code);
 
    return false;
  }
 
  code = curl_easy_setopt(conn, CURLOPT_URL, url);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
 
    return false;
  }
 
  code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
  if (code != CURLE_OK){
    fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
 
    return false;
  }
  
  code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
 
    return false;
  }
  
  code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, (void *)&rec);
  if (code != CURLE_OK){
    fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
 
    return false;
  }
  
  return true;
}

static int writer(char *contents, size_t size, size_t nmemb, void *userp){
  size_t realsize = size * nmemb;
  struct receiveData *rec = (struct receiveData *)userp;

  rec->memory = realloc(rec->memory,rec->size + realsize + 1);
  if(rec->memory == NULL){
    printf("not enough memory (realloc returned NULL)\n");

    return 0;
  }

  memcpy(&(rec->memory[rec->size]), contents, realsize);
  rec->size += realsize;
  rec->memory[rec->size] = 0;
  
  return realsize;
}
1

Co to znaczy to samo?
Poza tym zdajesz sobie sprawę z tego, że musisz też inne rzeczy pozmieniać? Np. ta linia pozostała taka sama, co prawie na pewno jest błędem:

code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, (void *)&rec);
0

czyli co zamiast tego powinno tam byc ?

1

Wcześniej rec było struct receiveData, co sugeruje, że curl_easy_setopt() przyjmuje wskaźnik do tej struktury jako ostatni argument.
Teraz rec jest struct receiveData*, więc wywołanie prędzej powinno wyglądać tak:

code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, (void*) rec);
0

No zamienilem tak jak napisales ale dalej to nie pomoglo

1

conn w funkcji main przekazujesz przez wartość (wskaźnika), zmiana otrzymanego w funkcji init nie aktualizuje tego w main.

Wróć do kursu, niezbyt rozumiesz jak działają wskaźniki.

0

wiem juz ogarnalem, naprawione wszystko

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<curl/curl.h>
#include<stdbool.h>
 
struct receiveData{
  char *memory;
  size_t size;
};
 
static char errorBuffer[CURL_ERROR_SIZE];
char *receiveInput();
static bool init(CURL **conn, char *url, struct receiveData *rec);
static int writer(char *data, size_t size, size_t nmemb, void *userp);
 
int main(int argc, char *argv[]){
  CURL *conn = NULL;
  CURLcode code;
  char buffer[100];

  struct receiveData recDat;

  recDat.memory = malloc(1);
  recDat.size = 0;
  
  if (argc != 3 || (strcmp(argv[1], "pl") == 0 && strcmp(argv[1], "en") == 0)){
    fprintf(stderr, "Usage: %s pl/en <url>\n", argv[0]);
 
    exit(EXIT_FAILURE);
  }
 
  if(strcmp(argv[1], "pl") == 0)
    sprintf(buffer, "http://translatica.pl//translate.php?direction=plen&source=%s", argv[2]);
  if(strcmp(argv[1], "en") == 0)
    sprintf(buffer, "http://translatica.pl//translate.php?direction=enpl&source=%s", argv[2]);
 
  curl_global_init(CURL_GLOBAL_DEFAULT);
 
  if (!init(&conn, buffer, &recDat)){
    fprintf(stderr, "Connection initializion failed\n");
 
    exit(EXIT_FAILURE);
  }

  code = curl_easy_perform(conn);
  curl_easy_cleanup(conn);
 
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to get '%s' [%s]\n", argv[2], errorBuffer);
 
    exit(EXIT_FAILURE);
  }
  else
    printf("%s\n", recDat.memory);
 
  return 0;
}
 
static bool init(CURL **conn, char *url, struct receiveData *rec){
  CURLcode code;

  *conn = curl_easy_init();
  if(conn == NULL){
    fprintf(stderr, "Failed to create CURL connection\n");
 
    exit(EXIT_FAILURE);
  }
 
  code = curl_easy_setopt(*conn, CURLOPT_ERRORBUFFER, errorBuffer);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set error buffer [%d]\n", code);
 
    return false;
  }
 
  code = curl_easy_setopt(*conn, CURLOPT_URL, url);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
 
    return false;
  }
 
  code = curl_easy_setopt(*conn, CURLOPT_FOLLOWLOCATION, 1L);
  if (code != CURLE_OK){
    fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
 
    return false;
  }
 
  code = curl_easy_setopt(*conn, CURLOPT_WRITEFUNCTION, writer);
  if(code != CURLE_OK){
    fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
 
    return false;
  }
 
  code = curl_easy_setopt(*conn, CURLOPT_WRITEDATA, (void *)rec);
  if (code != CURLE_OK){
    fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
 
    return false;
  }

  return true;
}
 
static int writer(char *contents, size_t size, size_t nmemb, void *userp){
  size_t realsize = size * nmemb;
  struct receiveData *rec = (struct receiveData *)userp;
 
  rec->memory = realloc(rec->memory,rec->size + realsize + 1);
  if(rec->memory == NULL){
    printf("not enough memory (realloc returned NULL)\n");
 
    return 0;
  }
 
  memcpy(&(rec->memory[rec->size]), contents, realsize);
  rec->size += realsize;
  rec->memory[rec->size] = 0;
 
  return realsize;
}

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