соединение cstrings с помощью strtok, работает только при первом выполнении цикла

Я пытаюсь использовать strtok для объединения строки, прочитанной в cstring, на отдельные строки. Да, я знаю, что с строковыми объектами это можно сделать намного проще, но мне не разрешено их использовать. Когда этот код выполняется, он отлично работает с первой строкой, затем он продолжает работать только с этой же строкой на каждой итерации цикла. Файл успешно считывается в массив символов 'line', что подтверждается cout ‹* line ‹* endl; Однако strtok и второй цикл while продолжают разделять первую прочитанную строку каждый раз. Каждая строка содержит идентификатор first_name last_name и шесть оценок. Думаю, я просто перепишу его и сделаю разделитель getline на пробел и прочитал в отдельных строках, но знает ли кто-нибудь, почему strtok сращивает только первую строку на каждой последующей итерации цикла?

это сегмент кода, предположим, что все переменные правильно объявлены где-то в другом месте

 while(!fin.eof())
    {//while open
    fin.getline(line, 40, '\n');
    cout << line << endl;
    ptr = strtok (line, " ");

    while(ptr != NULL)
        {
        if(c==0)
          sprintf(firstname, "%s", ptr);
        if(c==1)
          sprintf(lastname, "%s", ptr);
        if(c==2)
          sprintf(id, "%s", ptr);
        if(c==3)
          sprintf(grade1, "%s", ptr);
        if(c==4)
          sprintf(grade2, "%s", ptr);
        if(c==5)
          sprintf(grade3, "%s", ptr);
        if(c==6)
          sprintf(grade4, "%s", ptr);
        if(c==7)
          sprintf(grade5, "%s", ptr);
        if(c==8)
          sprintf(grade6, "%s", ptr);
        ptr = strtok (NULL, " ");
        if(ptr == NULL)
          break;
        c++;
        }
}

person user1768079    schedule 13.02.2013    source источник
comment
Ваш c ++ очень забавный :-(   -  person qPCR4vir    schedule 13.02.2013
comment
Что ты имеешь в виду? Я новичок в C ++. Только настоящее программирование, которое я делал, - это Python. В моей школе преподают c ++, и внезапно один из моих учителей решает, что ему не нравятся строковые объекты, и заставляет нас использовать cstrings без видимой мне причины. Так что, если вы имеете в виду мое использование cstrings и функций типа sprintf и strtok, а не потоковых функций и строковых объектов, я согласен. Это очень странно.   -  person user1768079    schedule 13.02.2013
comment
Хорошо я понял. Вы тренируете C, а не C ++, но буквально пишете стили смешивания C ++ :-). Кроме того, решение if слишком "ручное" (использовать переключатель / прерывание?)… Или просто последовательный синтаксический анализ…? Думаю, теперь ты просто хочешь, чтобы он работал ...   -  person qPCR4vir    schedule 13.02.2013
comment
strtok сломан, и его не следует использовать никогда. Он поддерживает глобальное состояние, что делает невозможным обслуживание любой программы, использующей его.   -  person James Kanze    schedule 13.02.2013
comment
Кроме того, while ( fin.eof() ) неверно, так как пытается использовать результаты fin.getline без проверки его успешности.   -  person James Kanze    schedule 13.02.2013
comment
И наконец, почему вам нельзя использовать std::string? Если это курс, то вы не должны были видеть char[] до тех пор, пока не увидели std::string.   -  person James Kanze    schedule 13.02.2013
comment
Я не знаю, почему нам не разрешено использовать std :: string. Возможно, чтобы усложнить? Я не уверен. Это курс CS второго уровня, книга, которую мы используем, предназначена для C ++, и ожидается, что мы будем использовать C ++, а не C. Мы еще не узнали об объектах и ​​объектно-ориентированном программировании, поэтому, возможно, учитель не хочет, чтобы мы использовали std :: string без понимания классов и ADT, но, опять же, в инструкциях явно говорится, что нельзя использовать строковые объекты или связанные с ними методы. Поверьте, я бы предпочел использовать строковые объекты, так как я с ними более знаком.   -  person user1768079    schedule 13.02.2013


Ответы (2)


Вы не сбрасываете переменную c после выхода из внутреннего цикла.

person Some programmer dude    schedule 13.02.2013
comment
Спасибо, я не понимаю, как я это пропустил. - person user1768079; 13.02.2013

Как @Joachim Pileborg, основная проблема - сброс c. Можно было бы более явно инициализировать его перед входом во внутренний цикл c=0; и добавить и else для каждого if, кроме последнего.

person qPCR4vir    schedule 13.02.2013
comment
Ах да, используйте else if вместо просто if. Извините, я написал это довольно быстро вчера вечером. - person user1768079; 13.02.2013