Hi eVeryone,

Please help me on below code. I don't know what's the erorr mean.

Error Message
*test.c: In function ‘main’:
test.c:12:2: warning: passing argument 2 of ‘tokenise’ from incompatible pointer type [enabled by default]
test.c:5:6: note: expected ‘char **’ but argument is of type ‘char * (*)[100]’
test.c: In function ‘tokenise’:
test.c:22:6: warning: assignment makes pointer from integer without a cast [enabled by default]
test.c:28:7: warning: assignment makes pointer from integer without a cast [enabled by default]
*

#include <stdio.h>
#define MAX_NUM_TOKENS  100

void tokenise(char inputLine[], char * tokens[]);

void main()
{
    char *result;
    char inputLine[] = "Testing program Testing program";
    char *tokens[MAX_NUM_TOKENS];
    tokenise(inputLine, &tokens);
    printf("token: %s", tokens);
}

void tokenise(char inputLine[], char * tokens[])
{
    int i = 0;
    char *pch;

    pch =strtok(inputLine, " ");

    while(pch != NULL)
    {
        tokens[i] = pch;
        i++;
        pch = strtok(NULL, " ");
    }
}

I wanted to pass the inputLine from MAIN to Tokenise then in Tokenise split the inputLine with the delimiter space. After spliting then put it back to the tokens[]. I have used by reference for the tokens. But i am facing some issue with the by reference that i could not really understand. Can some one please guide me and let me understand what's the problem with the code?

Thank you for your time and effort.

The actual error is that you're adding an unnecessary level of indirection in the tokenise call. tokens is already an array of pointers, there's no need for the address-of operator.

However, that said you still have issues in the program. Most notable is the next line tries to print tokens as a single string when it's really an array of strings. You need to loop over the array and print each string individually. Further, tokenise should return the number of tokens so that you know when to stop the loop.

Compare and contrast, I fixed other minor issues like including string.h and not using void main:

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

#define MAX_NUM_TOKENS  100

int tokenise(char inputLine[], char * tokens[]);

int main(void)
{
    char inputLine[] = "Testing program Testing program";
    char *tokens[MAX_NUM_TOKENS];
    int n = tokenise(inputLine, tokens);
    int i;

    for (i = 0; i < n; i++) {
        printf("token: %s\n", tokens[i]);
    }

    return 0;
}

int tokenise(char inputLine[], char * tokens[])
{
    int i = 0;
    char *pch;

    pch = strtok(inputLine, " ");

    while (pch != NULL)
    {
        tokens[i] = pch;
        i++;
        pch = strtok(NULL, " ");
    }

    return i;
}

Hi deceptikon,

Thank you for your assistance. I have mix up pointers and by reference.

Can you help me to understand why void main() wouldn't work? why must it be int main(void)?
What is the difference between them?

Thanks

I have mix up pointers and by reference.

"By reference" in C is "by pointer". That's how you simulate pass by reference because there's not an actual reference type available. Pointers are close enough though, and colliquially we simply say that you're passing by reference instead of passing by simulated reference using a pointer. ;)

Can you help me to understand why void main() wouldn't work?

The only two signatures of main that the C standard specifies as universally correct are:

int main(void)
int main(int argc, char *argv[]);

Equivalent parts like char **argv and different names for the parameters are acceptable as well.

Returning void from main is only supported by a subset of compilers, and if the compiler you're using doesn't support it, using void main invokes undefined behavior. Undefined behavior is among the worst possible results for a program because it removes all predictability.

Edited 3 Years Ago by deceptikon

What deceptikon said about main(). All modern compilers will require the int return type unless (in some cases) you tell the compiler you are building legacy (old) code. The old K&R compilers would allow void return type for main(), but no longer (by default).

All modern compilers will require the int return type unless (in some cases) you tell the compiler you are building legacy (old) code. The old K&R compilers would allow void return type for main(), but no longer (by default).

You're thinking about implicit int, I suspect. This is no longer supported as of C99:

main()
{
    return 0;
}

The int return type is still there, it's just implied. One problem with this feature is that people would assume that no return type meant no return statement was required, which isn't the case.

Support of void as a return type from main is completely a compiler extension and always has been. Even K&R C specified main as returning int.

Thank both for the explaination. I have been always using void main() and it's working fine. I will use int void(....) in the future to avoid such issue again.

Thank you both for the guidance.

This question has already been answered. Start a new discussion instead.