2010-12-15 2 views
2

У меня есть проблема в strtock в C++ мне нужно прочитать follwing строку из файлапроблема strtok в C++

6: 00,6: 20,6: 40,7: 00,7: 20, 7: 40,8: 00,8: 50,9: 40,10: 30,11: 20,12: 00 Длина строки неизвестна (я не знаю, сколько аргументов у меня есть);

я пытаюсь сделать эту функцию:

void RailwayLine::initilizeLoz(char line[1024]) 
{ 

    char * pch; 
    char * timeReader; 
    Hour *hour; 
    char * pch2=NULL; 
    int time; 
    int minute; 
    char line2[1024]; 
    strcpy(line2,line); 
    pch = strtok (line2,","); 
while (pch != NULL) 
    { 
    delete pch2; 
    pch2= new char(strlen(pch)+1); 
    if(pch2!=NULL) 
    strcpy(pch2,pch); 
    timeReader = strtok (pch2,":"); 
    time=atoi(timeReader); 
    timeReader = strtok (NULL,":"); 
    minute=atoi(timeReader); 
    hour=new Hour(time,minute); 

      this-> UpdateLoz((*hour)); 

      pch=strtok(NULL,","); 


    } 


} 

, но это не работает. itj читает только первый аргумент (7:10)! что может быть затуханием? Как я могу улучшить свой код? спасибо

+1

Этот код имеет место утечка памяти , `pch2` не будет удаляться после последней итерации. Зачем вам удалять его в начале цикла, а не в конце, когда вы его используете? – jdmichal 2010-12-15 16:40:53

+1

Нет смысла проверять «NULL» после «новой» памяти. Если `new` failed, это вызовет исключение` std :: bad_alloc` и проверка `NULL` никогда не будет достигнута. Если вы хотите проверить «NULL», передайте `std :: nothrow` на вызов` new`; иначе замените «NULL» чек с помощью «try-catch». – Praetorian 2010-12-15 16:51:45

ответ

6

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

0

Я не думаю, что вы можете вставить strtok, как вы это сделали, - когда вы запускаете поиск «:», он забывает о предыдущем экземпляре, который вы собирали для выделения разделенных запятыми элементов.

2

Абсолютный лучший способ улучшить код - прекратить использование stroke и использовать то, что использует силу используемого вами языка. У Boost есть токенизатор и другие библиотеки, которые могут реально удовлетворить ваши потребности (например, регулярное выражение).

Ход в stroke не является забавным видом; это то, что вы получаете в своем мозгу. Ужасная, ужасная функция, конструкция которой восходит к темным временам программирования. У него серьезные и постоянные проблемы, которые делают его не только устаревшим, но и опасным ... как вы видите здесь. Прекратите пытаться строить вещи, заставляя камни и палки вместе. Приходите в современную эпоху, где у нас есть кузницы и робототехника. Спаси свой мозг!

1

Я бы использовал алгоритм Boost Split или Tokenizer. Но если у вас нет Boost, вы можете сделать что-то вроде этого:

std::istringstream iss(line); 
std::string departure; 
while (getline(iss, departure, ',')) 
{ 
    // departure has one time in it; 
    // do what you will with it 
} 
0

Это сделало бы эту работу.


void tokenize(std:: string stringToTokenize) {

char* pch = new char [ (stringToTokenize.length()) + 1 ]; 

    std:: strcpy(pch, stringToTokenize.c_str()) ; 

    pch = std:: strtok(pch, ",") ; 

    std::cout << std::endl ; 

    while(pch != NULL) { 

    std::cout << pch << std::endl ; 
    pch = strtok(NULL, ",") ; 

    } 

}

INT основных (INT ARGC, Const символ * ARGV []) {

std:: string s1 ; std:: getline(std::cin, s1) ; tokenize(s1) ; return 0 ;

}