How can I access a global pointer outside of a C function?
I am trying to access the data of*tkn
within a different function in my program for example: putchar(*tkn);
It is a global variable but its not working correctly. Any ideas?
#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++;
}
}
}
In this line:
while ((*tkn != 0) && (tkn != NULL))
you need to reverse the conditions. If tkn
is a null pointer, you will crash when the first term is evaluated. If you need to check a pointer for validity, do so before dereferencing it.
while (tkn != NULL && *tkn != '\0')
The extra parentheses you added do no harm but are not necessary. And although 0
is a perfectly good zero, the '\0'
emphasizes that *tkn
is a character. Of course, given the prior tkn != NULL
condition in the if statement, there is no real need to repeat the check in the while loop.
Working code based on yours - some work left to do for subsequent tokens in the string, for example...
#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);
}
Sample output:
token1: abc
token = <<abc>>
token1: abcdefghijklmnopqrs
token = <<abcdefghijklmnopqrs>>
Asked:
But what if I am taking in a string 'abc 3fc ghi' and I want to use just '3fc' in another function that say converts it from ascii to hex? How do I just use say tkn2 for 3fc and get that only using a pointer? – patrick 9 mins ago
That's where it gets trickier because strtok()
has a moderately fiendish interface.
Leaving tokenize()
unchanged, let's redefine str
:
char *str;
Then, we can use (untested):
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);
}
Clearly, this relies on knowing that there are three tokens. To generalize, you'd need the tokenizer to tell you when there's nothing left to tokenize.
Note that having tkn
as a global is really unnecessary - indeed, you should aim to avoid globals as much as possible.
You should use
tkn++
rather than
*tkn++
Just use strlcpy(3)
instead of hand-coding the copy (hint - you are forgetting string zero terminator):
strlcpy( array, tkn, MAX );
Although tkn
itself is a global variable, you also have to make sure that what it points to (ie. *tkn
) is still around when you try to use it.
When you set tkn
with a line like:
tkn = strtok (str," ");
Then tkn
is pointing to part of the string that str
points to. So if str
was pointing to a non-static array declared in a function, for example, and that function has exited - then *tkn
isn't allowed any more. If str
was pointing to a block of memory allocated by malloc()
, and you've called free()
on that memory - then accessing *tkn
isn't allowed after that point.
精彩评论