2013-09-13 2 views
0

Новичок здесь, несколько смущен насчет упражнения: Tutorial Последний на странице (это немецкий). Я должен читать HTML-строки и атрибуты печати и их значения. Дается объявление функции, которая должна использоваться.
Меня раздражают две вещи:
1. Линия хранится в строке const char, но я бы хотел, чтобы Пользователь напечатал нужную HTML-строку. Кажется, не удастся изменить переменную const во время выполнения. Как это может быть достигнуто без изменения данной декларации?
2. Учебное пособие хочет, чтобы я вернул позицию strtok-поиска как целое число, но я читал в Интернете, что это значение хранится в strtok, есть ли способ сделать это или получить его каким-то образом?Обучение c получение указателя позиции из strtok as int

Чтобы решить упражнение, я написал этот код, но программа вылетает во время выполнения с «Ошибка сегментации (ядро сбрасывается)» - сообщение, и я не знаю, почему, может кто-нибудь объяснить это мне? (Я, вероятно, нужно таНос, но для какой переменной?)

//cHowTo Uebung Teil 2 Nr. 4 
//HTMLine.c 

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

//char getHTMLline(); 
int getHtmlAttributes(const char *string, int start, char *attrNamem,char *attrValue); //given by Tutorial 

int main(int argc, char *argv) //because i want user-input later on, if possible 
{ 
    const char strg[]= {"<img src=\"kurt.jpg\" width=\"250\" alt=\"Kurt Kanns\" />"}; //given example line by tutorial 
    char attriN[255]={0}, attriV[255]={0}; 
    int pos=99; 
    //printf("Please type the tag for analysis.\n"); 
    //fgets(strg, 255, stdin);     
    printf("attribute\tvalue\n\n"); 
    do 
    { 
    pos = getHtmlAttributes(strg, pos, attriN, attriV); //pos should be strtok-search-position 
    printf("%s\t\t%s\n", attriN, attriV); 
    } 
    while(pos!=1); 
    return EXIT_SUCCESS; 
} 

int getHtmlAttributes(const char *string, int start, char *attrNamem, char *attrValue) 
{ 
    int i, len; 
    char *ptr; 
    len = strlen(string); 
    char stringT[len]; //variable used to be split by strtok 


    for(i=0; i<len; i++) 
    stringT[i]=string[i];//copy string to stringT 
    if(start==99) 
    ptr = strtok(stringT, "<="); //get first attribute as whole 
    else 
    ptr = strtok(NULL, "= "); // get following attributes 
    for(i=0; i<len; i++) 
    attrNamem[i] = ptr[i]; 

    ptr = strtok(NULL, "\""); //get values 

    for(i=0; i<len; i++) 
    attrValue[i] = ptr[i]; 

    if(ptr == NULL) //if search complete 
    { 
    return 1; 
    } 
    else // if search continues 
    { 
    return 0; 
    } 

} 

//char getHTMLline() 
//{ 
// char user_input; 
// scanf("%s", &user_input); 
// return user_input; 
//} 
+0

Запустите его в отладчике или выбросьте в какой-либо файл printf(), чтобы сузить место, где он сбой. – John3136

+0

Вам необходимо выделить память для 'attrName' и 'attrValue', которые вы вернетесь. Вернитесь на страницу учебного пособия о массивах и/или 'char *' -строчных строках и перечитайте их :) – us2012

+0

Я думал, что было бы (достаточно) память зарезервирована с помощью 'char attriN [255] = {0}, attriV [ 255] = {0}; ' – rrrrn

ответ

0

Что strtok() делает то, что если вы вызываете его со строкой, отличной от NULL он хранит указатель на эту строку внутренне и возвращает первый маркер. Последующий вызов с NULL затем использует этот внутренний указатель для определения следующего токена.

Теперь то, что происходит в вашем коде: При вызове getHtmlAttributes() в первый раз при создании копии данной string в stringT и передать эту копию в strtok(). При следующем звонке strtok(NULL, ...). И там у нас есть две ошибки:

  1. ваш цикл, чтобы скопировать string() в stringT() не является правильным. Вы не скопировали тем оформления '\0'. Просто используйте strcpy() в таких случаях
  2. важных один: Когда вы звоните getHtmlAttributes() во второй раз, вы называете strtok(NULL, ...), но время жизни stringT, что она была вызвана с первоначально закончились первый вызов getHtmlAttributes() возвращения, потому что stringT это локальная переменная, которая создается заново каждый раз при вызове функции. Вы могли бы решить эту проблему, либо
    • объявляющего static char stringT[N] где N должна быть постоянной (например, 255), вы не можете использовать len (что должно было len+1 так или иначе) в этом случае
    • создания динамически выделяемый копию string от char *stringT = strdup(string);. Пожалуйста, сделайте это, только если вы вызываете strtok(stringT, ...) aferwards и имейте в виду, что без дополнительного кода у вас есть утечка памяти, потому что вы не можете снова освободить эту память.
    • что бы я хотел: используйте string напрямую, а не stringT. В этом случае вы не должны объявить string константным и создать копию strg в main(), что вы передаете функции

Редактировать Я думаю, что запрос «отплатить позицию strtok-поиска как целое "означает, вы должны вернуть смещение найденного токена в полную строку.Это довольно легко достичь, если использовать предлагаемое решение static char stringT[N] сверху: Как strtok() работ по строке, передаваемой при первом вызове, после получения ptr отличается от NULL, можно вычислить и вернуть int offset = ptr - stringT;

Edit 2

а теперь нечто совсем другое

Я только что прочитал учебник вы связаны с (привет из Гессена :-)), и я думаю, что идея заключается в том, чтобы использовать новый strtok() цикл каждый раз, когда вызывается функция. Это может понравиться:

int getHtmlAttributes(const char *string, int start, char *attrName, char *attrValue) 
{ 
    char *buf; 
    char *attrptr; 
    char *ptr; 

    // copy the substring starting at start to buf 
    // you should add error checking (buf may become NULL) 
    buf = strdup(string+start); 

    // first step: tokenize on whitespace; we stop at the first token that contains a "=" 
    for(attrptr = strtok(buf, " \t"); attrptr && (ptr = strchr(attrptr, '=')) != NULL; attrptr = strtok(NULL, " \t")) ; 

    if(attrptr) { 
      // copy everything before "=" to attrName 
      sprintf(attrName, "%.*s", ptr-attrptr, attrptr); 
      // copy everything after "=" to attrValue 
      strcpy(attrValue, ptr+1); 

      // the next start is the current start + the offset of the attr found 
      // + the length of the complete attr 
      start += (attrptr - buf) + strlen(attrptr); 
      free(buf); 
      return start; 
    } else { 
      // no more attribute 
      free(buf); 
      return -1; 
    } 
} 
+0

Спасибо за ваш ответ. Я скопировал теперь правильно из 'string' в' stringT'. Поскольку мне не разрешено изменять декларацию 'getHtmlAttributes()' -declaration, второй раз вызов функции является причиной возврата позиции strtok, что подразумевается упражнением (я думаю). – rrrrn

+0

Я бы интерпретировал запрос differenlty, см. Мое редактирование –

+0

Спасибо за ваше время! Я закончил это с помощью 'start = (ptr-stringT) + strlen (ptr) +1; начало возврата; ' – rrrrn

Смежные вопросы