2014-10-16 5 views
1

У меня есть текстовый файл, в котором содержится много писем, в начале каждого письма есть 3 строки информации заголовка, среди которых: From :, Subject :, Date :. Я знаю, что после каждого символа ctrl-L строки заголовка, следовательно, строка c == 12.Манипулирование строк в C

В настоящее время мой из массива получает 1 строку текста либо что-то вроде:

From: Rollen Awen <[email protected]> 

или

From: [email protected] 

Так прямо сейчас я пытаюсь использовать разделители только сохранить адрес электронной почты, но им не уверен, как это сделать. Я должен быть в состоянии справиться с любой ситуацией, независимо от того, заключен ли она в пределах <> или если она заключена между двумя пробелами.

Например, я хочу, чтобы изменить строку в

From: Rollen Awen <[email protected]> в только [email protected]

Или изменения

From: [email protected] в [email protected]

... 
FILE *emaildata = fopen (argv[1], "r"); 

    while((c=fgetc(emaildata))!=EOF){ 
      if(c==12){ 
       numberemails++; 
       fgets(nothing, sizeof(nothing), emaildata); 
       fgets(from, sizeof(from), emaildata); 
       fgets(subject, sizeof(subject), emaildata); 
       fgets(date, sizeof(date), emaildata); 
       //printf("%s", from); 
      } 
    ... 
+0

Одним из решений может быть: поиск строки для символа «@». как только вы обнаружите, что он вернется, пока не получите «действительные символы адреса электронной почты», а затем снова начните оттуда, пока не получите «действительные символы адресов электронной почты»! Но я сомневаюсь, что это эффективное решение! – Nullpointer

+0

Что вы подразумеваете под «заключенным между двумя пробелами»? – ooga

+0

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

ответ

3

Это требует memrchr() который Glibc дает вам, если вам #define _GNU_SOURCE. Если у вас нет этой функции, я уверен, что вы можете найти аналогичную или написать ее самостоятельно.

// input is either like "John Smith <[email protected]>" or "[email protected]" 
// leading and trailing whitespace is skipped 
// email is an out-param, must be an array at least as long as input 
void parse_email_address(const char* input, char* email) 
{ 
    // skip leading whitespace 
    while (isspace(*input)) { 
    ++input; 
    } 

    size_t len = strlen(input); 

    // ignore trailing whitespace 
    while (len > 0 && isspace(input[len - 1])) { 
    --len; 
    } 

    // parse friendly addresses like "John Smith <[email protected]>" 
    // '>' must come last, and '<' must come before it 
    if (len > 0 && input[len - 1] == '>') { 
    const char* left = memrchr(input, '<', len); 
    if (left) { 
     len -= left - input + 2; // 2 for '<' and '>' 
     input = left + 1; 
    } 
    } 

    memcpy(email, input, len); 
    email[len] = '\0'; 
} 
+0

Ummm, но он не обрабатывает адресные строки, такие как 'From: muller @ ngc.csc.ncsu.spu', не так ли? Возможно, я что-то пропустил. Если я прав, я думаю, что «найти« @ »и промежуток оттуда более надежный. – luk32

+0

@ luk32: предполагается, что вы отрубили 'From:' уже. Конечно, эта часть проста, но я должен был бы более четко рассказать об этом. Я добавлю комментарий. –

+0

О, я думал, что «вход» - это линия. Но разве это не путешествие, когда нет '<' and '>'? EDIT: Хорошо, я думаю, что вижу. Извините за путаницу. Это приятная встречная часть идеи «find' @ 'и span from it», которая также хороша IMO. – luk32