Ошибка при использовании указателя на линейные токены в C - PullRequest
0 голосов
/ 14 марта 2020

Я создал программу, которая требует чтения файла CSV, который содержит банковские счета и историю транзакций. Для доступа к определенной информации у меня есть функция getfield, которая читает токен каждой строки по токену:

const char* getfield(char* line, int num)
{
    const char *tok;
    for (tok = strtok(line, ",");
            tok && *tok;
            tok = strtok(NULL, ",\n"))
    {
        if (!--num)
            return tok;
    }
    return NULL;
}

. Я использую это позже в своем коде для доступа к номеру счета (в позиции 2) и транзакции. сумма (позиция 4):

...
while (fgets(line, 1024, fp))
{


        char* tmp = strdup(line); 

        //check if account number already exists

        char *acc = (char*) getfield(tmp, 2); 
        char *txAmount = (char*)getfield(tmp, 4);

        printf("%s\n", txAmount);
        //int n =1;
        if (acc!=NULL && atoi(acc)== accNum && txAmount !=NULL){
                if(n<fileSize)
                {
                        total[n]= (total[n-1]+atof(txAmount));
                        printf("%f", total[n]);
                        n++;

                }

         }
         free(tmp1); free(tmp2);
}
...

Кажется, что с char *acc = (char*) getfield(tmp, 2) не возникает никаких проблем, но когда я использую getfield для char *txAmount = (char*)getfield(tmp, 4), следующее предложение печати показывает, что у меня всегда есть NULL , Для контекста, файл в настоящее время читается как (первая строка пуста):


AC,1024,John Doe
TX,1024,2020-02-12,334.519989
TX,1024,2020-02-12,334.519989
TX,1024,2020-02-12,334.519989

Я ранее спрашивал, требуется ли использовать free(acc) в отдельной части моего кода ( Бесплатно ( ) ошибка указателя при приведении из const char *) и ответ, похоже, был нет, но я надеюсь, что этот вопрос дает лучший контекст. Это проблема с не высвобождением txAmount? Любая помощь с благодарностью!

(Также, если у кого-то есть лучшее предложение для названия, пожалуйста, дайте мне знать, как я мог бы лучше сформулировать его, я довольно новичок в переполнении стека)

Ответы [ 2 ]

1 голос
/ 14 марта 2020

Проблема в том, что strtok заменяет найденные разделители на '\0'. Вам нужно будет получить бесплатную sh копию строки.
Или продолжить с того места, где вы остановились, используя getfield (NULL, 2).

1 голос
/ 14 марта 2020

Ваша getfield функция изменяет свой ввод. Поэтому, когда вы снова вызываете getfield для tmp, вы не вызываете ее для правильной строки.

Для удобства вы можете захотеть создать функцию getfield, которая не изменяет свой ввод , Это будет неэффективно, но я не думаю, что производительность или эффективность особенно важны для вашего кода. Функция getfield вызовет strdup на своем входе, извлечет возвращаемую строку, вызовет strdup для этого, free дубликат исходного ввода, а затем вернет указатель на дубликат найденного поля. Вызывающая сторона должна free вернуть указатель.

...