views:

974

answers:

6

I have the following code:

#include <string.h>

int main(void) {
    char *buffer = NULL, **words = NULL, *aPtr = NULL, *sPtr;
    int count = 0;

    buffer = strdup("The quick brown fox jumps over the lazy dog");
    sPtr = buffer;

    do {
     aPtr = strsep(&sPtr, " ");

     words[count++] = ... // missing code
    } while(aPtr);

    return 0;
}

I'm missing some code as you can see above... Is there any kind of strdup() that works on this situation? The strdup() function itself doesn't seem to work... If there isn't one, how can I make this piece of code work?

Pointer of pointer is headache for me...

+2  A: 

As yet you have not allocated words[0], words[1], ... so using strdup doesn't help.

Worse, you don't know in advance how many words there are going to be, so it is not trivial to malloc the space you need.

One option is to replace words with a linked list, or a dynamic array.

dmckee
+2  A: 

You need to allocate space for words array, something like:


#define MAX_NUM_WORDS 1024
...
/* on the stack */
char* words[MAX_NUM_WORDS];
...
/* or on the heap */
char** words;
if (( words = ( char** )malloc( MAX_NUM_WORDS * sizeof( char* ))) == NULL )
{
    perror( "malloc" );
    exit( 1 );
}

Or better yet - use dynamic data structure like a singly-linked list.

Nikolai N Fetissov
+1  A: 

Your first problem is that you want a list for words - you could get away by hardcoding some limits in words (an array of N words, and each word is an address), but that's not really production-quality. The real solution is to have a list (which could be implemented as a growing array internally)

I don't see the problem with strdup, but you should void strsep, the function does not have a good API. It would almost be easier to do what strsep does by hand.

David Cournapeau
+1  A: 

You need a dynamically allocated array. You could roll your own, but why not use Seq_T from Dave Hanson's C Interfaces and Implementations? The Seq_addhi function will do exactly what you want.

Norman Ramsey
+2  A: 

you might use something simple if just for trying it:

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

#define MAX_WORDS 100

int main(void) {
    char *buffer, *words[MAX_WORDS], *aPtr;
    int count = 0, i;

    buffer = strdup("The quick brown fox jumps over the lazy dog");
    if (!buffer) return 1;

    do {
        aPtr = strsep(&buffer, " ");
     if (aPtr && count < MAX_WORDS) words[count++] = aPtr;
    } while(aPtr && count < MAX_WORDS);

    for (i = 0; i < count; i++) {
     printf("%s\n", words[i]); 
    }
    return 0;
}

running it:

[macbook:~] jianlin $ ./a.out
The
quick
brown
fox
jumps
over
the
lazy
dog
[macbook:~] jianlin $
動靜能量
A: 

the loop above was a bit clumsy, so i changed it to:

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

#define MAX_WORDS 100

int main(void) {
    char *buffer, *words[MAX_WORDS], *aPtr;
    int count = 0, i;

    buffer = strdup("The quick brown fox jumps over the lazy dog");
    if (!buffer) return 1;

    while((aPtr = strsep(&buffer, " ")) && count < MAX_WORDS)
     words[count++] = aPtr;

    for (i = 0; i < count; i++) {
     printf("%s\n", words[i]); 
    }
    return 0;
}

the output is the same.

動靜能量