Как я могу получить доступ к глобальному указателю вне функции C? - PullRequest
0 голосов
/ 13 апреля 2010

Я пытаюсь получить доступ к данным *tkn в другой функции моей программы, например: putchar(*tkn); Это глобальная переменная, но она работает неправильно. Есть идеи?

#define MAX 20
// globals
char *tkn;
char array[MAX];
...


void tokenize()
{

int i = 0, j = 0;
char *delim = " ";


tkn = strtok (str," ");         // get token 1
if (tkn != NULL) {
    printf("token1: ");

    while ((*tkn != 0) && (tkn != NULL))
    {
        putchar(*tkn);
        array[i] = *tkn;
        *tkn++;
        i++;
    }
   }                
}

Ответы [ 4 ]

2 голосов
/ 13 апреля 2010

В этой строке:

    while ((*tkn != 0) && (tkn != NULL))

вам нужно отменить условия. Если tkn является нулевым указателем, то произойдет сбой при оценке первого члена. Если вам нужно проверить правильность указателя, сделайте это перед разыменованием.

    while (tkn != NULL && *tkn != '\0')

Добавленные вами дополнительные скобки не причиняют вреда, но не являются необходимыми. И хотя 0 является совершенно хорошим нулем, '\0' подчеркивает, что *tkn является символом. Разумеется, учитывая предыдущее условие tkn != NULL в операторе if, нет реальной необходимости повторять проверку в цикле while.


Рабочий код, основанный на вашем коде - осталось проделать некоторую работу для последующих токенов в строке, например ...

#include <stdlib.h>
#include <string.h>

enum { MAX = 20 };
char *tkn;
char array[MAX];
char str[2*MAX];

void tokenize(void)
{
    int i = 0;

    array[0] = '\0';

    tkn = strtok(str, " ");         // get token 1
    if (tkn != NULL)
    {
        printf("token1: ");
        while (tkn != NULL && *tkn != '\0' && i < MAX - 1)
        {
            putchar(*tkn);
            array[i++] = *tkn++;
        }
        *tkn = '\0';
        putchar('\n');
    }
}

int main(void)
{
    strcpy(str, "abc def");
    tokenize();
    printf("token = <<%s>>\n", array);
    strcpy(str, "abcdefghijklmnopqrstuvwxyz");
    tokenize();
    printf("token = <<%s>>\n", array);
    return(0);
}

Пример вывода:

token1: abc
token = <<abc>>
token1: abcdefghijklmnopqrs
token = <<abcdefghijklmnopqrs>>

На вопрос:

Но что, если я беру строку 'abc 3fc ghi' и хочу использовать просто '3fc' в другой функции, которая скажет, преобразует ее из ascii в hex? Как мне просто использовать скажем tkn2 для 3fc и получить это только с помощью указателя? - Патрик 9 минут назад

Вот тут-то и становится все сложнее, потому что strtok() имеет умеренно злобный интерфейс.

Оставив tokenize() без изменений, давайте переопределим str:

char *str;

Тогда мы можем использовать (не проверено):

int main(void)
{
    char buffer[2*MAX];
    strcpy(buffer, "abc 3fc ghi");
    str = buffer;
    tokenize();
    printf("token = <<%s>>\n", array); // "abc"
    str = NULL;
    tokenize();
    printf("token = <<%s>>\n", array); // "3fc"
    str = NULL;
    tokenize();
    printf("token = <<%s>>\n", array); // "ghi"
    return(0);
}

Очевидно, это зависит от знания, что есть три токена. Чтобы обобщить, вам понадобится токенизатор, который сообщит вам, когда нечего токенизировать.

Обратите внимание, что наличие tkn в качестве глобального действительно не нужно - на самом деле, вы должны стремиться избегать глобальных значений в максимально возможной степени.

1 голос
/ 13 апреля 2010

Вы должны использовать

ТКН ++

вместо

* ТКН ++

0 голосов
/ 13 апреля 2010

Хотя tkn сама по себе является глобальной переменной, вы также должны убедиться, что то, на что она указывает (т. Е. *tkn), все еще присутствует, когда вы пытаетесь ее использовать.

Когда вы устанавливаете tkn со строкой вроде:

tkn = strtok (str," ");

Тогда tkn указывает на часть строки, на которую указывает str. Так, если str указывал на нестатический массив, объявленный, например, в функции, и эта функция завершилась - тогда *tkn больше не разрешен. Если str указывал на блок памяти, выделенный malloc(), и вы вызвали free() в этой памяти - тогда доступ к *tkn не разрешен после этой точки.

0 голосов
/ 13 апреля 2010

Просто используйте strlcpy(3) вместо ручного кодирования копии (подсказка - вы забываете нулевой терминатор строки):

strlcpy( array, tkn, MAX );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...