2014-09-30 7 views
0

Я хочу разделить тематическое содержание письма в один текстовый файл, другие поля заголовка в следующий текстовый файл, наконец, тело сообщения в другой текстовый файл. Мой код может извлекать поля электронной почты с одной строкой content.but он не извлекается, если поле имеет более одной строки. (Это необходимо, потому что такие поля, как Subject, To an и так далее, могут иметь несколько строк.) plz help me ... Мой код приведен ниже:категоризация содержимого электронной почты

название

программы: f2all.c

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

int main (int argc, char **argv) { 

    if (argc < 5) { 
     fprintf (stderr, "Error: insufficient input. Usage: %s input_file output_file\n", 
      argv[0]); 
     return 1; 
    } 

    FILE *ifp = fopen(argv[1],"r"); 
    FILE *ofp1 = fopen(argv[2],"w");/*this points to a file(eg:f.txt),which should contain`contents of subject field only*/ 
    FILE *ofp2= fopen(argv[3],"w");/*this points to a file(eg:g.txt),which should contain contents of all other other header field only*/ 
    FILE *ofp3= fopen(argv[4],"w");/*this points to a file(eg:h.txt),which should contain contents of message body only*/ 

    char *buf = NULL; 
    char *buf1 = NULL; /* forces getline to allocate space for buf */ 
    ssize_t read = 0; 
    size_t n = 0; 
    char *ptr = NULL; 

    if (ifp==NULL)  
    {  
     printf("\nFile cannot be opened\n"); 
     return 1; 
    } 
    else 
    { 
     while ((read = getline (&buf, &n, ifp)) != -1) 
     { 
      if (((ptr=strstr(buf,"Subject:")) != 0)) 
      { 
       fprintf(ofp1,"%s",(ptr+8));  /* use (ptr + 8) to trim 'Subject:` away */ 
      } 
      if ((ptr=strstr(buf,"subject :")) != 0) 
      { 
       fprintf(ofp1,"%s",(ptr+9));   
      } 

      if (((ptr=strstr(buf,"Date:")) != 0)||((ptr=strstr(buf,"From:")) != 0)||((ptr=strstr(buf,"X-cc:")) != 0)) 
      { 
       fprintf(ofp2,"%s",(ptr+5));   
      } 
      if ((ptr=strstr(buf,"X-To:")) != 0) 
      { 
       fprintf(ofp2,"%s",(ptr+5));     
      } 
      else 
      { 
       strcpy(buf1,buf); 
       fprintf(ofp1,"%s",buf1); 

      } 
     } 
    } 
    if (buf)  /* free memory allocated by getline for buf */ 
     free (buf); 
    fclose(ofp1); 
    fclose(ofp2); 
    fclose(ofp3); 
    fclose(ifp); 

    return 0; 
} 

Я сделал компиляцию, а затем запустить программу следующим образом:

princy @ PRINCY: ~/minipjt/SUBJECT $ cc f2all.c f2all.c: В функции 'main': f2all.c: 85: 9: warning: несовместимое неявное объявление встроенной функции 'free' [по умолчанию включено] princy @ PRINCY: ~/minipjt/ПРЕДМЕТ $ ./a.out 8.txt f.txt g.txt h.txt вина Сегментация (ядро сбрасывали)

+1

'#include ' для того, чтобы использовать 'свободный()' ' –

+1

buf1' никогда не выделяется, но вы называете' STRCPY (Buf1, БУФ); ' –

ответ

0

Вы можете установить контекст когда сканирование через файл, а затем печать в выходной поток в соответствии с этим контекстом. В противном случае ваши условия будут сохраняться только для первой строки каждой записи заголовка.

В этом свете имеет смысл хранить массив указателей выходных файлов.

Ваш код разбивает ключевое слово из записей заголовка. Это означает, что при чтении выходного файла будет потерян контекст: [email protected] отправитель, получатель или предпочтительный адрес для ответов?

Пример реализации, основанный на вашем ниже.

#define _GNU_SOURCE 1 

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

enum { 
    SUBJECT, 
    HEADER, 
    BODY, 
    NONE = -1 
}; 

/* 
*  Check whether the line starts with any of the given keywords in 
*  kw. If so, return a pointer to the char after the colon. If not, 
*  return NULL. The array kw must be terminated with NULL. 
*/ 
const char *is_header(const char *line, const char **kw) 
{ 
    while (*kw) { 
     int l = strlen(*kw); 

     if (strncmp(line, *kw, l) == 0 && line[l] == ':') { 
      /* Note: Could use strncasecmp here for case-insenitive matching */ 
      return line + l + 1; 
     } 
     kw++; 
    } 

    return NULL; 
} 

const char *header_subject[] = { 
    "Subject", NULL 
}; 

const char *header_other[] = { 
    "From", "To", "Date", /* ... */ NULL 
}; 

int main(int argc, char **argv) 
{ 
    if (argc < 5) { 
     fprintf(stderr, 
      "Error: insufficient input. Usage: %s input_file output_file\n", 
      argv[0]); 
     return 1; 
    } 

    FILE *ifp; 
    FILE *ofp[3]; 

    ifp = fopen(argv[1], "r"); 
    ofp[0] = fopen(argv[2], "w"); 
    ofp[1] = fopen(argv[3], "w"); 
    ofp[2] = fopen(argv[4], "w"); 

    /* Omitted: Error checking for file opening/creatinon */ 

    char *buf = NULL; 
    size_t n; 
    int context = NONE; 

    while (getline(&buf, &n, ifp) != -1) { 
     const char *line = buf; 

     if (context != BODY) { 
      /* Check for context if we are not already in the body */ 
      const char *p; 

      /* Strip white space from string */ 
      while (*line == ' ' || *line == '\t') line++; 

      if (*line == '\n' || *line == '\r') {     
       context = BODY;  /* An empty line starts the body ... */ 
       continue;   /* ... but we don't print it. */ 
      } 

      p = is_header(buf, header_subject); 
      if (p) { 
       line = p; 
       while (*line == ' ' || *line == '\t') line++; 
       context = SUBJECT; 
      } 

      p = is_header(buf, header_other); 
      if (p) { 
       line = p; 
       while (*line == ' ' || *line == '\t') line++; 
       context = HEADER; 
      } 
     } 

     if (context != NONE) fprintf(ofp[context], "%s", line); 
    } 

    if (buf) free(buf); 
    fclose(ofp[0]); 
    fclose(ofp[1]); 
    fclose(ofp[2]); 
    fclose(ifp); 

    return 0; 
}