Ошибка ошибки сегментации при записи потока Twitter в текстовый файл - PullRequest
0 голосов
/ 22 ноября 2011

У меня есть программа на C, которая открывает поток твитов из Twitter API. Цель этой программы - открыть поток и записать поток в текстовый файл. Эта программа успешна, когда она просто печатает поток в терминале, но когда я изменяю код для записи в файл, возникает ошибка «Ошибка сегментации» в течение примерно 40 секунд. size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s) - это функция обратного вызова, которая записывает поток в файл, особенно на

fp=fopen("istream.txt", "a");
fprintf(fp, "%s", s->ptr);
fclose(fp);

Почему возникает ошибка «ошибка сегментации»? Как мне это исправить? Наверное, я неправильно использую указатель файла.

==================================

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

struct string {
  char *ptr;
  size_t len;
};

void init_string(struct string *s) {
  s->len = 0;
  s->ptr = malloc(s->len+1);
  if (s->ptr == NULL) {
    fprintf(stderr, "malloc() failed\n");
    exit(EXIT_FAILURE);
  }
  s->ptr[0] = '\0';
}

size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
{
  size_t new_len = s->len + size*nmemb;
  size_t max_buffer = 10240;
  FILE *fp;
  fp=fopen("istream.txt", "a"); // <------------- the ERROR! Remove this.

  s->ptr = realloc(s->ptr, new_len+1);
  if (s->ptr == NULL) {

    fprintf(stderr, "realloc() failed\n");
    exit(EXIT_FAILURE);
  }
  memcpy(s->ptr+s->len, ptr, size*nmemb);
  s->ptr[new_len] = '\0';
  s->len = new_len;

  if( s->len >= max_buffer )
  {
    fp=fopen("istream.txt", "a");
    fprintf(fp, "%s", s->ptr);
    fclose(fp);

    fflush( stdout );
    free(s->ptr);
    init_string( s );
  }

  return size*nmemb;
}

int main(void)
{
  CURL *curl;
  CURLcode res;


  curl = curl_easy_init();
  if(curl) {
    struct string s;
    init_string(&s);

    curl_easy_setopt(curl, CURLOPT_URL, "https://stream.twitter.com/1/statuses/sample.json");
    //curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
    curl_easy_setopt(curl, CURLOPT_USERPWD, "neilmarion:password");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
    res = curl_easy_perform(curl);

    //printf("%s\n", s.ptr);
    free(s.ptr);

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  return 0;
}

Ответы [ 2 ]

1 голос
/ 22 ноября 2011

Большинство вещей выглядит правильно в вашей программе.

Скорее всего, если fp=fopen("istream.txt", "a"); не удается открыть файл, это может быть ошибка в последовательной строке.

Попробуйте вместо этого напечатать строку в stderr. Если это работает, тогда проблема действительно в fp.

Другие комментарии:
Поскольку вы открываете файл в режиме добавления, на самом деле нет смысла собирать данные в буфере и продолжать перераспределять буфер. Вы можете сразу добавить файл.

0 голосов
/ 22 ноября 2011

Каждый раз, когда вы вводите writefunc, вы открываете istream.txt:

FILE *fp;
fp=fopen("istream.txt", "a");

, но никогда не набираете fclose на fp.У вас есть это:

fp=fopen("istreaam.txt", "a");
fprintf(fp, "%s", s->ptr);
fclose(fp);

позже, но второй fopen означает, что у вас больше нет ссылки на то, что вернул первый fopen.

В конце концов, вы будетезакончились открытые файлы, и дальнейшие вызовы fopen не будут выполнены.По-видимому, это занимает около 40 секунд.Так что избавьтесь от первого fopen и попробуйте снова.

...