Reputation: 11
I need to type a function getWord () that takes a string and an integer as argument. The function should return a pointer to the beginning of the word to which it refers. If word is 0, a pointer to the first word in the string will be returned, if word is 1, a pointer to the second word will be returned, etc. If word is greater or equal to the number of words in the string, NULL must be returned.
Example run:
ptr = getWord ("hello you", 1); / * "you" returns * /
ptr2 = getWord ("a string", 0); / * "a" returns * /
ptr3 = getWord ("one word", 2); / * NULL returns * /
void getWord(char string[])
{
int i;
for (i = 0; i < strlen(string); i++)
{
if (isalpha(string[i]))
printf("%c", string[i]);
if (string[i] == ' ')
break;
}
}
Upvotes: 1
Views: 8529
Reputation: 23784
Try this simple idea.
First try to implement a next
function like this:
char* next( const char* str )
{
const char delimiter = ' ';
// skip all characters up to the first ' '
while( *str != delimiter && *str != '\0' ) ++str;
// may the first characters is ' ', so skip it as well
while( *str == delimiter ) ++str;
return str;
}
okay, let's test:
int main( )
{
const char* first = next( "one two three four five" );
puts( first );
first = next( first );
puts( first );
first = next( first );
puts( first );
first = next( first );
puts( first );
}
its output:
LSP ❱ ./a.out
two three four five
three four five
four five
five
LSP ❱
Now we need to tell the next
function that not only goes to the next word but also count how many, thus is becomes:
char* next( const char* str, int index )
{
const char delimiter = ' ';
// take care of index for us
while( index-- ){
while( *str != delimiter && *str != '\0' ) ++str;
while( *str == delimiter ) ++str;
}
if( *str == '\0' ) return NULL;
return str;
}
let's test:
int main( )
{
puts( next( "one two three four five", 0 ) );
puts( next( "one two three four five", 1 ) );
puts( next( "one two three four five", 2 ) );
puts( next( "one two three four five", 3 ) );
puts( next( "one two three four five", 4 ) );
if( next( "one two three four five", 5 ) == NULL )
puts( "NULL was returned" );
}
and:
LSP ❱ ./a.out
one two three four five
two three four five
three four five
four five
five
NULL was returned
LSP ❱
int main( )
{
// 1. skip white space
puts( next( "one two three four five", 3 ) );
// returns: 'four five'
puts( "---------------" );
// 2. easy iteration over a string
const char* first = "one two three four five";
while( ( first = next2( first ) ) != NULL )
{
puts( first );
}
}
outputs:
LSP ❱ ./a.out
four five
---------------
two three four five
three four five
four five
five
LSP ❱
For returning just a word based on an index, you can use strdup
see man 3 strdup
and strchr
, see man 3 strchr
. Thus inside the next function
you should add (after while loop):
char* next( char* str, int index )
{
const char delimiter = ' ';
while( index-- ){
while( *str != delimiter && *str != '\0' ) ++str;
while( *str == delimiter ) ++str;
if( *str == '\0' ) return NULL;
}
// duplicate the current string
char* result = strdup( str );
// find the first whitespace and make it as NUL
result [strchr( result, ' ' ) - result ] = '\0';
if( *result == '\0' ) return NULL;
return result;
}
and inside the main:
int main( )
{
char* r = next( "one two three four five", 3 );
if( r != NULL )
{
puts( r );
free( r );
}
else
{
puts( "there is no word at index 3" );
}
char* s = next( "one two three four five", 8 );
if( s != NULL )
{
puts( s );
free( s );
}
else
{
puts( "there is no word at index 8" );
}
}
test:
LSP ❱ gcc -fsanitize=address temp.c
LSP ❱ ./a.out
four
there is no word at index 8
LSP ❱
NOTE for next2
just add:
if( *str == '\0' ) return NULL;
to the first next
and names it next2
Also you should check the return value of strdup
it may be NULL
Upvotes: 0
Reputation: 12669
This getWord() returns the (n+1)th word of input string:
char * getWord(char * string, int n)
{
char str[1024] = {'\0'};
char * delim = " \t";
char * pch = NULL;
char * result = NULL;
int i = 0;
if (string == NULL)
return NULL;
strcpy (str, string);
pch = strtok (str, delim);
while (pch != NULL)
{
if (i == n)
break;
pch = strtok (NULL, delim);
i++;
}
if (pch != NULL)
{
result = (char *)malloc(strlen(pch) + 1);
if (result == NULL)
printf ("Failed to allocate memory\n");
else
strcpy (result, pch);
}
return result;
}
If this function returns the result as not NULL, make sure to free the memory allocated to "result" variable in the function which is calling getWord().
The main() will look something like this -
int main ()
{
char * ptr;
ptr = getWord ("hello you", 1);
if (ptr != NULL)
{
printf ("ptr = %s\n", ptr);
free(ptr);
}
else
printf ("ptr is NULL");
return 0;
}
Upvotes: 0
Reputation: 310950
We beginners should help each other.:)
Here you are.
#include <stdio.h>
#include <string.h>
char * getWord(const char *s, size_t n)
{
while ( ( s += strspn(s, " \t") ) != '\0' && n-- )
{
s += strcspn(s, " \t");
}
return *s ? (char *)s : (char *)0;
}
int main( void )
{
char *s = "Hi Adrian. How are you?";
size_t n = 0;
for (char *p; (p = getWord(s, n)) != NULL; ++n)
{
printf("%zu: %s\n", n, p);
}
printf("\nThere are %zu words in the string\n", n);
return 0;
}
The output of the demonstrative program is
0: Hi Adrian. How are you?
1: Adrian. How are you?
2: How are you?
3: are you?
4: you?
There are 5 words in the string
If you want to get the output like this
0: Hi
1: Adrian.
2: How
3: are
4: you?
There are 5 words in the string
then just rewrite the loop in main the following way
for (char *p; (p = getWord(s, n)) != NULL; ++n)
{
size_t len = strcspn(p, " \t");
printf("%zu: %*.*s\n", n, ( int )len, ( int )len, p);
}
Upvotes: 1
Reputation: 1
This is what you can do
char* get_word (char *string,int req_num)
{
int i;
int ns;//number of spaces
int *sp;
ns=0;
for(i=0;string[i]!='\0';i++)
{
//check for a spaces and increment ns
if (string[i]==' ')
{
++ns;
sp=(int*)realloc(sp,ns*sizeof(int));
sp[ns-1]=(int)&string[i+1];
}
//check what place you have to return
if(req_num>=ns)
return NULL;
else
return (char*)sp[req_num];
}
}
This code is very un-optimized and you can comeup with ways to restructure the code to optimize it to run it faster.
Upvotes: 0