Member Avatar for dmmckelv

OK Can anyone help me understand what a tokenizer does? And why I have to put *tokenPtr? What is the * for?

I am having a heck of a time figuring out how to write a program that takes the last two letters of a word in a sentence puts them on the front of a new word and adds 'ay' to the end of the word then moves to the next word in the sentence and starts over. It is an online class so I can't ask the teacher for help in class and the assignment is due tomorrow. I have some sample code from the book but it isn't helping me. The following is my start.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

#include <cstring>
using std::strtok;
using std::strlen;


const int SIZE = 80;

// function prototype
void printLatinWord( const char *token );

int main()
{
char sentence[ SIZE ];
char *tokenPtr;

cout << "Enter a sentence:\n";
cin >> sentence;

*tokenPtr = strtok( sentence, " " );

while ( *tokenPtr != NULL )
{
    printLatinWord( *tokenPtr )
    *tokenPtr = strtok( NULL, " " );//get next token
}
return 0;
}

void printLatinWord ( const char *token )
{
cout << strlen( token );
}

Thanks for any help!:?:

OK Can anyone help me understand what a tokenizer does? And why I have to put *tokenPtr? What is the * for?

The tokenizer basically looks for one or more deliminators which you specify, and then gives you the next section. You need this to split the sentance into individual words. To do so, your deliminator will of course be " ".

The reason you need * in front of your token is because strtok returns a pointer, which you need your token to point to. So to to change what the pointer points to, you don't use the * in front of its name thus, these lines are incorrect:

*tokenPtr = strtok( sentence, " " ); // should be just tokenPtr = ...
 
while ( *tokenPtr != NULL ) // should be just tokenPtr != NULL
{
    printLatinWord( *tokenPtr ); // printLatinWord(tokenPtr);
    *tokenPtr = strtok( NULL, " " ); // tokenPtr = strtok(NULL, " ");

But you've got the tokenizer idea correct. Now, all you've got to do is understand pointers, which the link I provided should help you do, and then printLatinWord() should be non-trivial.

Well, I'm a noob myself, but I noticed that you have a long way to go on this...

First, instead of repetatively naming all the members of std, use;
using namespace std;
It kills all those birds with one stone! (I hope there's no PETA folks reading this!)

i think the the Include should be:
#include <string.h>

strlen returns the length of a string. So why are you using it with cout?

>> i think the the Include should be:
>> #include <string.h>

string.h is used in C programs. C++ should use cstring as the OP posted. He did it correctly.

Also, using namepace std is not always better than what the OP did. His way is fine.

why?

why?

There is always more than one way to do something and often one way is just as good as any other. Some things are just a matter of programmer preference. Some programmers don't like declaring "using namespace std" becuse they claim it brings everything in std namespace into scope. Myself, I say "so what? -- the compiler can handle that very well, thank you". But there is nothing at all wrong with not doing that either.

There is always more than one way to do something and often one way is just as good as any other. Some things are just a matter of programmer preference. Some programmers don't like declaring "using namespace std" becuse they claim it brings everything in std namespace into scope. Myself, I say "so what? -- the compiler can handle that very well, thank you". But there is nothing at all wrong with not doing that either.

Yes, and that *can* conflict with other functions in the current scope with the same names -- something that makes debugging difficult if you don't know that you're mistakenly calling the wrong function. I've seen lots of programming books and code refuse to use using namespace std; and simply prefix all objects in the std library with std:: .

Member Avatar for dmmckelv

Still having trouble with the code. I did what joeprogrammer said and changed all of the *tokenPtr to tokenPtr and now I can't get the program to compile. If someone can help me pass the word into the function I think I could finish the program. I have the cout line down there just to see what is making it to my function, and it appears to be something that strlen can't handle. Following is the code and the compiler errors. Thanks for any help!

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

#include <cstring>
using std::strtok;
using std::strlen;


const int SIZE = 80;

// function prototype
void printLatinWord( const char *token );

int main()
{
char sentence[ SIZE ];
char *tokenPtr;

cout << "Enter a sentence:\n";
cin >> sentence;

tokenPtr = strtok( sentence, " " );

while ( *tokenPtr != NULL )
{
    printLatinWord( tokenPtr );
    tokenPtr = strtok( NULL, " " );//get next token
}
return 0;
}

void printLatinWord ( char tokenPtr )
{
cout << strlen( tokenPtr );
}

warning C4996: 'strtok' was declared deprecated c:\program files\microsoft visual studio 8\vc\include\string.h(164) : see declaration of 'strtok' Message: 'This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

: warning C4996: 'strtok' was declared deprecated c:\program files\microsoft visual studio 8\vc\include\string.h(164) : see declaration of 'strtok' Message: 'This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

: error C2664: 'strlen' : cannot convert parameter 1 from 'char' to 'const char *' Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast

warning C4996: 'strtok' was declared deprecated c:\program files\microsoft visual studio 8\vc\include\string.h(164) : see declaration of 'strtok' Message: 'This function or variable may be unsafe. Consider using strtok_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

Reinterpretation of this warning:
We at Microsoft know better than the standards committee that created the standards for C and C++. We therefore decree our way is better and don't give a flying %&#$ what the standard says. Switch to our proprietory functions so your programs aren't cross platform -- giving us domination over the computer industry. Mwah haaa haaaa!!!!! :twisted:
In other words, ignore them.


: error C2664: 'strlen' : cannot convert parameter 1 from 'char' to 'const char *' Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast

What type of value is tokenPtr. What type of value does strlen() require?

Member Avatar for dmmckelv

OK next question. I am trying to change the array tokenPtr is pointing to. My compiler will not let me save tokenPtr as a char[]. How can I access different array positions using tokenPtr? I need to take the first letter of the array and put it on the end... here is what I came up with.

Also my while loop is only doing the first word in the sentence. Any ideas? Oh yeah... every time I run this I get an error asking me to send a report to Microsoft. I think this means some loop in here is not working properly and I am assuming it is this while loop. I am not that familiar with tokens so it is hard for me to understand where the problem is.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

#include <cstring>
using std::strtok;
using std::strlen;


const int SIZE = 80;

// function prototype
void printLatinWord( char const * const  );

int main()
{
char sentence[ SIZE ];
char *tokenPtr;

cout << "Enter a sentence:\n";
cin >> sentence;

tokenPtr = strtok( sentence, " " );

while ( *tokenPtr != NULL )
{
    printLatinWord( tokenPtr );
    tokenPtr = strtok( NULL, " " );//get next token
}
return 0;
}

void printLatinWord ( char const * const tokenPtr )
{
    //cout << tokenPtr << " " <<strlen( tokenPtr ) << endl;
    long length = strlen( tokenPtr );
    cout << tokenPtr[length];
    for ( int x=0; x < length; x++)
    {
        cout << tokenPtr[length -(length - x)];
    }
    cout << "ay ";
}

Thanks again.

OK next question. I am trying to change the array tokenPtr is pointing to.

Since you have made the functino parameter as char const * const tokenPtr you can neither modify the poniter nor the data pointed by it if thats what you asking.

Also my while loop is only doing the first word in the sentence.

See my comment marked in red below.

Oh yeah... every time I run this I get an error asking me to send a report to Microsoft. I think this means some loop in here is not working properly and I am assuming it is this while loop. I am not that familiar with tokens so it is hard for me to understand where the problem is.

This message generally means segmentation fault which occurs when you try to access or change a memory location that doestn belong to you. Simply put its something bad related to pointers.

#include <iostream>
using std::cin;
using std::cout;
using std::endl;

#include <cstring>
using std::strtok;
using std::strlen;


const int SIZE = 80;

// function prototype
void printLatinWord( char const * const  );

int main()
{
char sentence[ SIZE ];
char *tokenPtr;

cout << "Enter a sentence:\n";
 cin >> sentence; 
// you need to use fgets( ) to get the entire sentence with
// whitespaces. cin stops at the first whitespace.

// if using C++ use cin.getline( )
 
tokenPtr = strtok( sentence, " " );

while ( *tokenPtr != NULL )
{
    printLatinWord( tokenPtr );
    tokenPtr = strtok( NULL, " " );//get next token
}
return 0;
}

void printLatinWord ( char const * const tokenPtr )
{
    //cout << tokenPtr << " " <<strlen( tokenPtr ) << endl;
    long length = strlen( tokenPtr );
    cout << tokenPtr[length];
    for ( int x=0; x < length; x++)
    {
        cout << tokenPtr[length -(length - x)];
    }
    cout << "ay ";
}

Hope it helped, bye.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.