View Full Version : [SOLVED] How to get data in the form of string using libcurl
bilalakhtar
March 22nd, 2010, 09:14 AM
Hi people,
Iam using libcurl from a C++ program. I want to make a Twitter client, with all calls to the API being made by libcurl. I am successful to some extent (my program can send tweets) but I can't get the tweets using libcurl in string form. Here is some code spec:-
CURL* handle = curl_easy_init();
curl_easy_setopt(handle,CURLOPT_URL,"http://api.twitter.com/1/statuses/home_timeline.xml");
curl_easy_setopt(handle,CURLOPT_USERPWD,m_userpwd. c_str());
I want to put the data in a Glib::ustring called m_tweets, which I could later on parse using libxml++ and display the tweets to the user.
I have searched the net for solutions, but most of the solutions cause a segfault for me.
bilalakhtar
March 23rd, 2010, 07:54 AM
bump? :popcorn: :guitar: :-({|=\\ :D/
heikaman
March 23rd, 2010, 11:02 AM
I don't see the problem here ? I'm assuming that you set the callback function using the CURLOPT_WRITEFUNCTION, right ? here's a small example:
#include <curl/curl.h>
size_t curl_write( void *ptr, size_t size, size_t nmemb, void *stream)
{
return fwrite(ptr, size, nmemb, stdout);
}
int main(int argc, char **argv)
{
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://ubuntuforums.org");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
Compile with:
gcc test.c -o test -lcurl && ./test
falconindy
March 23rd, 2010, 04:01 PM
It's slightly more involved to actually get it into a string, since the recv() call that triggers the write callback is buffered. The easiest way (i've found) is to declare struct that contains a char* and a integer value to keep track of how much you've written so that you can append after that.
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE (256 * 1024) /* 256kB */
struct write_result {
char *data;
int pos;
};
static size_t curl_write( void *ptr, size_t size, size_t nmemb, void *stream) {
struct write_result *result = (struct write_result *)stream;
/* Will we overflow on this write? */
if(result->pos + size * nmemb >= BUFFER_SIZE - 1) {
fprintf(stderr, "curl error: too small buffer\n");
return 0;
}
/* Copy curl's stream buffer into our own buffer */
memcpy(result->data + result->pos, ptr, size * nmemb);
/* Advance the position */
result->pos += size * nmemb;
return size * nmemb;
}
int main(int argc, char **argv) {
CURL *curl = curl_easy_init();
char *data;
/* Create the write buffer */
data = malloc(BUFFER_SIZE);
if (! data)
fprintf(stderr, "Error allocating %d bytes.\n", BUFFER_SIZE);
struct write_result write_result = {
.data = data,
.pos = 0
};
/* Set curl's parameters */
curl_easy_setopt(curl, CURLOPT_URL, "http://ubuntuforums.org");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result);
curl_easy_perform(curl);
/* null terminate the string */
data[write_result.pos] = '\0';
/* Print what we got. can't use printf because the data is too big */
fwrite(data, write_result.pos, sizeof(char), stdout);
/* Don't forget to free your memory! */
free(data);
curl_easy_cleanup(curl);
curl_global_cleanup();
}
I know this is C and not C++, but it should get you started (and it's what I wrote over the weekend >.>).
bilalakhtar
March 24th, 2010, 09:55 AM
It's slightly more involved to actually get it into a string, since the recv() call that triggers the write callback is buffered. The easiest way (i've found) is to declare struct that contains a char* and a integer value to keep track of how much you've written so that you can append after that.
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE (256 * 1024) /* 256kB */
struct write_result {
char *data;
int pos;
};
static size_t curl_write( void *ptr, size_t size, size_t nmemb, void *stream) {
struct write_result *result = (struct write_result *)stream;
/* Will we overflow on this write? */
if(result->pos + size * nmemb >= BUFFER_SIZE - 1) {
fprintf(stderr, "curl error: too small buffer\n");
return 0;
}
/* Copy curl's stream buffer into our own buffer */
memcpy(result->data + result->pos, ptr, size * nmemb);
/* Advance the position */
result->pos += size * nmemb;
return size * nmemb;
}
int main(int argc, char **argv) {
CURL *curl = curl_easy_init();
char *data;
/* Create the write buffer */
data = malloc(BUFFER_SIZE);
if (! data)
fprintf(stderr, "Error allocating %d bytes.\n", BUFFER_SIZE);
struct write_result write_result = {
.data = data,
.pos = 0
};
/* Set curl's parameters */
curl_easy_setopt(curl, CURLOPT_URL, "http://ubuntuforums.org");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result);
curl_easy_perform(curl);
/* null terminate the string */
data[write_result.pos] = '\0';
/* Print what we got. can't use printf because the data is too big */
fwrite(data, write_result.pos, sizeof(char), stdout);
/* Don't forget to free your memory! */
free(data);
curl_easy_cleanup(curl);
curl_global_cleanup();
}
I know this is C and not C++, but it should get you started (and it's what I wrote over the weekend >.>).
Sorry, falconindy, This solution causes a segfault for me, even though it compiles fine. I found exactly same solutions on the net, which didn't work.
heikaman
March 24th, 2010, 10:07 AM
Sorry, falconindy, This solution causes a segfault for me, even though it compiles fine. I found exactly same solutions on the net, which didn't work.
1) falconindy's code doesn't segfault
2) another way:
#include <curl/curl.h>
#include <cstdio>
#include <string>
std::string buffer;
size_t curl_write( void *ptr, size_t size, size_t nmemb, void *stream)
{
buffer.append((char*)ptr, size*nmemb);
return size*nmemb;
}
int main(int argc, char **argv)
{
CURL *curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, "http://ubuntuforums.org");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_write);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
fwrite( buffer.c_str(), buffer.length(), sizeof(char), stdout);
return 0;
}
bilalakhtar
March 26th, 2010, 07:28 AM
Thanks, heikman,
IT WORKS!
Powered by vBulletin® Version 4.2.2 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.