Struktura do funkcji

Odpowiedz Nowy wątek
2015-10-22 11:54
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 spowrotem w main.

Pozostało 580 znaków

2015-10-22 12:01
kq
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).


edytowany 1x, ostatnio: kq, 2015-10-22 12:06

Pozostało 580 znaków

2015-10-22 12:02
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

Pozostało 580 znaków

2015-10-22 12:25
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;
}
edytowany 1x, ostatnio: Nejm, 2015-10-22 12:25

Pozostało 580 znaków

2015-10-22 13:47
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);

Pozostało 580 znaków

2015-10-22 13:54
0

czyli co zamiast tego powinno tam byc ?

Pozostało 580 znaków

2015-10-22 15:03
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);
cast na void* jest raczej zbędny, tak przy okazji. - kq 2015-10-22 15:05
Niejawna konwersja w C jak mniemam? A czy jakaś nowa wersja C nie zmienia tych wymagań? - twonek 2015-10-22 15:17
Może C11 zmienia, natomiast C++14 nie, więc bardzo wątpię, żeby C to zmieniło (i złamało miliony linii działającego kodu). - kq 2015-10-22 15:24
§4 [conv]/1 Standard conversions are implicit conversions with built-in meaning. ⟶ §4.10 [conv.ptr]/2 A prvalue of type “pointer to cv T,” where T is an object type, can be converted to a prvalue of type “pointer to cv void”. - kq 2015-10-22 15:25
yhm, dzięki - twonek 2015-10-22 15:37

Pozostało 580 znaków

2015-10-22 15:43
0

No zamienilem tak jak napisales ale dalej to nie pomoglo

Pozostało 580 znaków

2015-10-22 15:45
kq
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.


edytowany 1x, ostatnio: kq, 2015-10-22 15:47

Pozostało 580 znaków

2015-10-22 16:22
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;
}
edytowany 1x, ostatnio: Nejm, 2015-10-22 16:22

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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