Obtención de tipos de cambio de divisas específicas desde el reparador utilizando CURL y JSCONCPP en C ++ -- ++ campo con json campo con web-scraping camp codereview Relacionados El problema

Fetching specific foreign exchange rates from fixer using curl and jsconcpp in C++


4
vote

problema

Español

Estoy tratando de crear mi propio sistema de comercio algorítmico usando C ++. He buscado en la web un buen tutorial para tales sistemas y no encontré ninguno. Luego comencé a aprender sobre [ ['Topic 1', [ 'Topic 1.1', [ ['Topic 1.1.1', []], ['Topic 1.1.2', []] ] ], ['Topic 2', []], ['Topic 3', [ ['Topic 3.1', []], ['Topic 3.2', []], ['Topic 3.3', []], ] ] ] 5 y [ ['Topic 1', [ 'Topic 1.1', [ ['Topic 1.1.1', []], ['Topic 1.1.2', []] ] ], ['Topic 2', []], ['Topic 3', [ ['Topic 3.1', []], ['Topic 3.2', []], ['Topic 3.3', []], ] ] ] 6 las bibliotecas e incluso la documentación de esas bibliotecas no están hechas para un programador novato como yo. En su mayoría, reutilizé la mayoría de los códigos para crear este raspador, especialmente [ ['Topic 1', [ 'Topic 1.1', [ ['Topic 1.1.1', []], ['Topic 1.1.2', []] ] ], ['Topic 2', []], ['Topic 3', [ ['Topic 3.1', []], ['Topic 3.2', []], ['Topic 3.3', []], ] ] ] 7 que copio directamente pegado de otro código C ++ sin entenderlo. Estoy compartiendo todo este código porque alguien más es necesario reinventar la rueda y puede usar este código como plantilla. Cualquier forma de que este código funciona correctamente (Ubuntu 14.04, CODEBLOCKS IDE, API: fijer.io ) y cualquier tipo de sugerencia o retroalimentación es bienvenida.

  [   ['Topic 1', [     'Topic 1.1', [        ['Topic 1.1.1', []],        ['Topic 1.1.2', []]     ]   ],   ['Topic 2', []],   ['Topic 3', [     ['Topic 3.1', []],     ['Topic 3.2', []],     ['Topic 3.3', []],     ]   ] ] 8  
Original en ingles

I am trying to create my own algorithmic trading system using C++. I have searched the web for a nice tutorial for such systems and I didnt find any. Then I started to learn about curl and jsoncpp libraries and even documentation of those libraries are not made for a novice programmer like me. I mostly reused most of the codes for creating this scrapper especially WriteCallback function which I directly copy pasted from another c++ code without understanding it. I am sharing this whole code because some one else dosent need to reinvent the wheel and can use this code as a template.Any way this code is working properly (Ubuntu 14.04, CodeBlocks IDE, API: fixer.io) and any kind of suggestion or feedback is welcomed.

#include <string.h> #include <iostream> #include <stdio.h> #include <jsoncpp/json/json.h> #include <curl/curl.h>  //writing call back function for storing fetched values in memory static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {     ((std::string*)userp)->append((char*)contents, size * nmemb);     return size * nmemb; }   int main(void) {   std::string readBuffer;    //global initiliation of curl before calling a function  curl_global_init( CURL_GLOBAL_ALL );   //creating session handle  CURL * myHandle;   // Wexe2x80x99ll store the result of CURLxe2x80x99s webpage retrieval, for simple error checking.  CURLcode result;    // notice the lack of major error-checking, for brevity  myHandle = curl_easy_init ( ) ;   //after creating handle we ill start transfering webpage   //curl_easy_setopt is used to tell libcurl how to behave.  //By setting the appropriate options, the application can change libcurl's behavior.   //CURLOPT_URL provide the URL to use in the request. Pass in a pointer to the URL to work with.  //sample json output >> {"base":"EUR","date":"2016-07-22","rates":{"GBP":0.84108,"USD":1.1014}}  curl_easy_setopt(myHandle, CURLOPT_URL, "http://api.fixer.io/latest?symbols=USD,GBP");     /* send all data to this function  */   curl_easy_setopt(myHandle, CURLOPT_WRITEFUNCTION, WriteCallback);     /* we pass our 'chunk' struct to the callback function */   curl_easy_setopt(myHandle, CURLOPT_WRITEDATA, &readBuffer);   //perform a blocking file transfer  result = curl_easy_perform( myHandle );   /* check for errors */   if(result != CURLE_OK) {     fprintf(stderr, "curl_easy_perform() failed: %s\n",             curl_easy_strerror(result));   }   else {     /*      * Now, our chunk.memory points to a memory block that is chunk.size      * bytes big and contains the remote file.      *      * Do something nice with it!      */      //std::cout << readBuffer << std::endl;      //json parsing Json::Value root;   // will contains the root value after parsing. Json::Reader reader; bool parsingSuccessful = reader.parse( readBuffer, root ); if(not parsingSuccessful)  {    // Report failures and their locations    // in the document.    std::cout<<"Failed to parse JSON"<<std::endl        <<reader.getFormatedErrorMessages()        <<std::endl;    return 1;  }else{  std::cout<<"\nSucess parsing json\n"<<std::endl;  std::cout << root<< std::endl;  std::cout <<"Base = "<< root["base"].asString() << std::endl;  std::cout <<"Date = "<< root["date"].asString() << std::endl;  std::cout <<"Rate GBP ="<< root["rates"]["GBP"].asFloat() << std::endl;  std::cout <<"Rate USD ="<< root["rates"]["USD"].asFloat() << std::endl;   }    }      //End a libcurl easy handle.This function must be the last function to call for an easy session  curl_easy_cleanup( myHandle );    return 0; } 
        
         
         

Lista de respuestas

2
 
vote
vote
La mejor respuesta
 

Estos son encabezados C

  #include <string.h> #include <stdio.h>   

Probablemente debería usar la versión C ++ (espero que no esté usando C-String en ninguna parte).

  #include <strings> #include <cstdio>   

El encabezado incluye rutas

  #include <jsoncpp/json/json.h>   

Esto debería ser, probablemente, json/json.h y debe especificar la ubicación donde se instala JSONCPP con las banderas del compilador.

CURL es una biblioteca C.

Por lo tanto, cualquier devolución de llamada debe ser funciones C (no funciones de C ++). No hay garantía en el Thay estándar que usan el mismo ABI.

  static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)   

debe ser:

  extern "C" size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)   

Nunca use C-Casts

c Casts son difíciles de detectar (en general). Pero también usar los moldes de C ++, puede marcar los moldes peligrosos por uisng el elenco apropiado.

      ((std::string*)userp)->append((char*)contents, size * nmemb);   

Yo usaría reinterpret_cast<> aquí. Para que sea fácil de detectar y usted sabe intuitivamente que esta es una operación peligrosa.

  reinterpret_cast<std::string*>(userp)->append(static_cast<char*>(contents), size * nmemb);   

Siempre verifique los códigos de error.

Todos los siguientes devuelven un código de error. Debe validar estas funciones trabajadas marcando este código de error.

   curl_global_init( CURL_GLOBAL_ALL );  curl_easy_setopt(myHandle, CURLOPT_URL, "http://api.fixer.io/latest?symbols=USD,GBP");  curl_easy_setopt(myHandle, CURLOPT_WRITEFUNCTION, WriteCallback);  curl_easy_setopt(myHandle, CURLOPT_WRITEDATA, &readBuffer);   

Prefiero #include <strings> #include <cstdio> 0 sobre #include <strings> #include <cstdio> 1

  #include <strings> #include <cstdio> 2  

La diferencia es que #include <strings> #include <cstdio> 3 también llama #include <strings> #include <cstdio> 4 en el flujo. No hay necesidad de lavar la corriente manualmente. El arroyo está diseñado para lavarse cuando también necesita. Cuando lo haces manualmente, hará que su código sea mucho más eficiente.

RAII

  #include <strings> #include <cstdio> 5  

Cuando ves este patrón. Deberías estar pensando en usar RAII. Esto se asegurará de que sus recursos se limpien correctamente en todas las situaciones (incluidas cuando se lanzaron excepciones). ¿La función se devuelve temprano (AKA #include <strings> #include <cstdio> 6 ).

 

These are C headers

#include <string.h> #include <stdio.h> 

You should probably use the C++ version (I hope you are not using C-String anywhere).

#include <strings> #include <cstdio> 

Header include paths

#include <jsoncpp/json/json.h> 

This should probably be json/json.h and you should specify the location where jsoncpp is installed with compiler flags.

Curl is a C library.

Therefore any callbacks should be C functions (not C++ functions). There is no guarantee in the standard thay they use the same ABI.

static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) 

Should be:

extern "C" size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) 

Never use C-Casts

C casts are hard to spot (in general). But also using C++ casts you can mark dangerious casts by uisng the appropriate cast.

    ((std::string*)userp)->append((char*)contents, size * nmemb); 

I would use reinterpret_cast<> here. So that it is easy to spot and you intuitively know that this is a dangerous operation.

reinterpret_cast<std::string*>(userp)->append(static_cast<char*>(contents), size * nmemb); 

Always check error codes.

All the following return an error code. You should validate these functions worked by checking this error code.

 curl_global_init( CURL_GLOBAL_ALL );  curl_easy_setopt(myHandle, CURLOPT_URL, "http://api.fixer.io/latest?symbols=USD,GBP");  curl_easy_setopt(myHandle, CURLOPT_WRITEFUNCTION, WriteCallback);  curl_easy_setopt(myHandle, CURLOPT_WRITEDATA, &readBuffer); 

Prefer "\n" over std::endl

 std::cout<<"\nSucess parsing json\n"<<std::endl;  std::cout << root<< std::endl;  std::cout <<"Base = "<< root["base"].asString() << std::endl;  std::cout <<"Date = "<< root["date"].asString() << std::endl;  std::cout <<"Rate GBP ="<< root["rates"]["GBP"].asFloat() << std::endl;  std::cout <<"Rate USD ="<< root["rates"]["USD"].asFloat() << std::endl; 

The difference is that std::endl also calls std::flush on the stream. There is no need to flush the stream manually. The stream is designed to flush when it needs too. When you do it manually you will make your code much more eneficent.

RAII

 myHandle = curl_easy_init ( ) ;  // STUFF  curl_easy_cleanup( myHandle ); 

When you see this pattern. You should be thinking of using RAII. This will make sure your resources are cleaned up correctly in all situations (including when exceptions are thrown) are the function returns early (aka return 1;).

 
 

Relacionados problema

9  Un raspador web que busca palabras predefinidas en artículos de noticias  ( A web scraper that looks for pre defined words in news articles ) 
Sigo siendo bastante nuevo en Python y Web-rasping, pero un colega me preguntó si podía construir un raspador web que podría ser utilizado por un Think Tank, ...

6  BFS / DFS Web Crawler  ( Bfs dfs web crawler ) 
He construido un rastreador web que comienza en una URL de origen y rastrea la web con un método BFS o DFS. Todo está funcionando bien, pero la actuación es h...

6  TRIVAGO Hotels Precio Checker  ( Trivago hotels price checker ) 
He decidido escribir mi primer proyecto en Python. Me gustaría escuchar alguna opinión de usted. Descripción del script: Generar URLS TrivAGO para hote...

1  Scraper de Python + Selenium para obtener resultados usando la búsqueda inversa  ( Python selenium scraper to grab results using reverse search ) 
He escrito algún código en Python en combinación con Selenium para raspar el resultado poblado de un sitio web después de realizar una búsqueda inversa. Mi ...

2  Utilización de apiss de vapor y raspado web  ( Utilization of steam apis and web scraping ) 
alguna información de fondo aquí: Este es un pequeño proyecto divertido que hice utilizando las API de vapor y el raspado web Esta es la primera vez que ...

4  Raspando html usando sopa hermosa  ( Scraping html using beautiful soup ) 
He escrito un script usando una hermosa sopa para raspar un poco de html y hacer algunas cosas y producir HTML de vuelta. Sin embargo, no estoy convencido con...

2  PHP Crawler para recoger comentarios sobre los artículos  ( Php crawler to collect comments on articles ) 
Tengo código que analiza las páginas web encuentra comentarios y guarda información sobre comentarios en DB. Tengo una matriz donde se almacenan todas las pág...

11  ¿Es esta la forma en ello a Web-Scrape a una imagen de portada de libros?  ( Is this the clojure way to web scrape a book cover image ) 
¿Hay una manera de escribir esto mejor o más de manera de engaño? Especialmente la última parte con with-open y el let . ¿Debo poner el formulario 9988776...

5  Cómo obtener información de los países de un sitio web que no está utilizando una verbanización consistente  ( Getting information of countries out of a website that isnt using consistent ve ) 
de este sitio web Necesitaba agarrar la información para cada país e insértelo en una hoja de cálculo de Excel. Mi plan original era usar mi programa y ...

3  Raspador de noticias de Google para buscar enlaces con historias similares  ( Google news scraper to fetch links with similar stories ) 
El siguiente código lleva una URL o el título a un artículo de noticias existente. busca en Google News usando el título. recoge todos los enlaces de ...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos