Почему эта комбинация strtol и strtok не работает?

Может ли кто-нибудь сказать мне, что не так с этим кодом?

for(int i=0;i<4;i++)
{
    long int a = strtol(strtok("1-2-3-4","-"),(char**)NULL,10);
    cout << a <<endl
}

Я использую Solaris Unix. Это дает мне ошибку сегментации.

Ошибка в strtol().


person Vijay    schedule 10.01.2012    source источник


Ответы (3)


Ошибка связана с вызовом strtok, а не с strtol. Вы не можете вызвать strtok для строкового литерала, так как он попытается изменить строку. Изменение строкового литерала приводит к неопределенному поведению в C++.

person Carl Norum    schedule 10.01.2012

Проблем легион.

Я ожидаю, что дамп ядра связан с тем, что строка "1-2-3-4" хранится в постоянной памяти, поэтому, когда strtok() изменяет ее (чтобы изолировать первый токен), программа аварийно завершает работу. Вы говорите, что авария произошла в strtol(); это предполагает, что возвращаемое значение из strtok() равно NULL.

Первый вызов strtok() использует строку в качестве аргумента; второй вызов передает NULL вместо него, чтобы указать «продолжить с того места, где вы остановились в прошлый раз». Как написано, если бы строка была модифицируемой, вы бы проанализировали 1 четыре раза.

Это ближе к правильному (хотя и непроверенному):

char  input[] = "1-2-3-4";
char *data = input;
for (int i = 0; i < 4; i++)
{
    char *token = strtok(data, "-");
    if (token != 0)
    {
        long int a = strtol(token, NULL, 10);
        cout << a << endl;
    }
    data = NULL;
}

В общем, нужно делать обнаружение ошибок из strtol(); более того, делать это весьма чревато. Однако с образцом строки вам не придется беспокоиться об этом.

person Jonathan Leffler    schedule 10.01.2012

Поскольку проблема уже обсуждалась, я хотел бы показать альтернативный подход:

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

    int main ()
    {
      long int a;
      char str[] ="1-2-3-4";
      char * pch;

      pch = strtok (str,"-");
      while (pch != NULL)
      {
         a = strtol(pch,(char**)NULL,10);
         cout << a <<endl;

        pch = strtok (NULL, "-");
      }
      return 0;
     }
person COD3BOY    schedule 10.01.2012