strtok
не является реентерабельным и используется внутри parseProcess
, поэтому следующие вызовы в main
используют другой контекст. Кроме того, strtok(raw, "\r\n");
рассматривает как '\r'
и '\n'
как разделители, так и любую последовательность этих символов, в результате чего strtok()
не будет возвращать пустые токены для пустых строк в исходной строке.
Что касается POSIX strtok_r
, следуя комментариям, он не работает в windows, однако у вас есть strtok_s
. Есть и другие способы сделать это, но, учитывая, что вы используете strtok()
, вот пример этого может быть реализован:
Живая демонстрация
struct Process parseProcess(char* input){
struct Process output;
char* temp = malloc(strlen(input) + 1); //notes 1, 2, 3
strcpy(temp, input);
char* strmax; //for **stmax parameter
char* token = strtok_r(temp, " ", &strmax);
for(int i = 0; i < 4; i++){
switch(i){
case 0:
output.timeArrived = atoi(token);
token = strtok_r(NULL, " ", &strmax);
break;
case 1:
output.processId = atoi(token);
token = strtok_r(NULL, " ", &strmax);
break;
case 2:
output.memorySizeReq = atoi(token);
token = strtok_r(NULL, " ", &strmax);
break;
case 3:
output.jobTime = atoi(token);
output.remainingTime = atoi(token);
token = strtok_r(NULL, " ", &strmax);
break;
}
}
free(temp); //free the allocated memory
return output;
}
Примечания:
- Зарезервировать место для нулевого терминатора, когда вы выделяете с помощью
strlen
. Выделение памяти стоит дорого, если вы можете, избегайте этого, в этом случае вы можете используйте char temp[strlen(input) + 1];
.
MSV C quibles с этим, потому что это массивы переменной длины и говорит, что это ошибка, это не так, VLA действительны в C, вы можете использовать g cc или clang компиляторы, если вы хотите их использовать.
sizeof(char)
не требуется, char составляет 1 байт на разных платформах.
//...
#ifdef _MSC_VER //improved portability
#define strtok_r strtok_s
#endif
int main()
{
char raw[] = "0 4 96 30\r\n3 4 64 60\r\n3 5 64 20\r\n3 2 32 40\r\n5 1 100 20\r\n20 3 4 30\r\n";
char* strmax;
char* line = strtok_r(raw, "\r\n", &strmax); //line == "0 4 96 30" OK
line = strtok_r(NULL, "\r\n", &strmax); //line == "3 4 64 60" OK
line = strtok_r(NULL, "\r\n", &strmax); //line == "3 5 64 20" OK
struct Process current = parseProcess(line);
line = strtok_r(NULL, "\r\n", &strmax); //line == "3 2 32 40" OK
line = strtok_r(NULL, "\r\n", &strmax); ///line == "5 1 100 20" OK;
return 0;
}