Eigenvalue
Eigenvalue

Reputation: 1133

Breaking up input from getline by spaces into an array of character pointers

I'm trying to take the input given from getline which will have spaces in it and take each word and put it into a array of character pointers. I wasn't really sure how to go about this. I know that there is strtok, but that just sort of takes the spaces out and makes it into one giant word for my understanding. Some insight would be very helpful.

Upvotes: 0

Views: 241

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 754440

This doesn't spoon-feed you the code, but the questions may guide you.

Questions to which you must know the answers:

  1. Do you need to process just the words from a single line at a time, or do you need to keep all the words already read in memory?
  2. If the same word appears several times, do you need to keep the separate appearances separate?
  3. Are there any reasonable upper bounds on the length of a line, the length of a word, or the number of words in a line? If you're keeping all words, will all the information fit in memory?

Assuming you're using POSIX getline(), then you can use it to allocate the storage for the words. You have to decide how to manage the storage for the array of pointers. A fixed size allocation is simplest, but a dynamically allocated array isn't very hard. If you are handling one line at a time, then life is easy. If you're accumulating data across lines, then you'd have to ensure that getline() allocates new space for each line — not hard, but requires a modicum of care. Either way, you need to be careful with releasing the space allocated by getline().

You could use strtok(), though if strtok_r() or strtok_s() is available, you should use one of those instead. (They're effectively interchangeable, though their behaviours on error are different. Note that the strtok_s() defined in C11 Annex K is different from both the others.)

Another option is to use strdup() to copy words as they're parsed, maybe using strchr() to find the spaces that mark the ends of words. You'd then use the same storage space repeatedly with getline() since you'd already have copies of the words.

Upvotes: 1

Mahonri Moriancumer
Mahonri Moriancumer

Reputation: 6003

So, you need to set an array of char pointers like this:

char *srcStr = "Now is the time for all good men";
                ^   ^  ^   ^    ^   ^   ^    ^
                p0 p1  p2  p3   p4  p5  p6   p7

A common approach to doing this is to search the string for the spaces.

char *srcStr = "Now is the time for all good men";
                   ^  ^   ^    ^   ^   ^    ^

Notice how each space is just one character off from where a pointer should be set.

Consider the following code:

...
char *ptrArray[10];
int   ptrIndex = 0;
char *cp = srcStr;

// ptrArray[0] points to "Now...", and increment the ptrIndex.
ptrArray[ptrIndex++] = cp;    

// Find the next space character.    
while((cp=strchr(cp, ' '))
   // If another space is found, assign the next pointer in
   // 'ptrArray' to the address of 'cp' plus one.
   ptrArray[ptrIndex++] = ++cp;

...    

This code the raw answer to the question. However, it may not produce the expected results. Specifically, if you were to print the pointer values:

printf("p0[%s]\n", ptrArray[0]); //Output: "Now is the time for all good men"
printf("p1[%s]\n", ptrArray[1]); //Output: "is the time for all good men"
printf("p2[%s]\n", ptrArray[2]); //Output: "the time for all good men"

An so-on.
If the intention is to limit the output (above) to only one word per pointer, instead of:

while((cp=strchr(cp, ' '))
   ptrArray[ptrIndex++] = ++cp;

the code could do this:

while((cp=strchr(cp, ' '))
   {
   *cp='\0';
   ptrArray[ptrIndex++] = ++cp;
   }

Which will exchange a '\0' in the srcStr where a space ' ' is found. Something like this:

char *srcStr = "Nowɸisɸtheɸtimeɸforɸallɸgoodɸmen";
                ^   ^  ^   ^    ^   ^   ^    ^
                p0 p1  p2  p3   p4  p5  p6   p7

Thus, placing a string termination character '\0' after each word, resulting in:

printf("p0[%s]\n", ptrArray[0]); //Output: "Now"
printf("p1[%s]\n", ptrArray[1]); //Output: "is"
printf("p2[%s]\n", ptrArray[2]); //Output: "the"
...

Upvotes: 0

Related Questions