-4

So I have a string called c. I am reading it in from a file using this:

fscanf(file, "%[^/0]", &c);

I have another variable declared as char* array[41]. I need this to be an array of the individual words/strings of c.

The issue is that I do not know how many individual words/strings will be in c, since I'm getting it as a whole line from a file. My idea was to put it into the array character by character and if it is white space i can replace it with null character, but I'm 95% sure that doesn't work at all. My other idea was if I could somehow know how many strings are in the line and capture each as a string to put in the array, but then I'm afraid it will mess with what comes after that line since I cannot be sure how many strings there are.

Taylor
  • 547
  • 2
  • 7
  • 16

2 Answers2

1

That's exactly what strtok(3) does. All you need to do is allocate an "array", for example

size_t num = 16;
char **arr = malloc(num * sizeof(char *));

then fill it with the results of strtok() and count ... if you reach num, do something like

if (count == num)
{
    num *= 2;
    arr = realloc(arr, num * sizeof(char *));
}

add error checking for malloc() and realloc().

  • Where does the 16 come from? Why have exponential growth? – Ed Heal Oct 12 '15 at 18:08
  • @EdHeal make it 1, will work, too. It's an assumption, nothing else. –  Oct 12 '15 at 18:09
  • @EdHeal and regarding your edit, that's a common idiom reducing the `realloc()` calls for large inputs dramatically. –  Oct 12 '15 at 18:10
  • What about the exponential growth? – Ed Heal Oct 12 '15 at 18:10
  • 1
    @EdHeal in general, allocate an amount suitable for >50% of the expected inputs, then double if it turns out to be to little. It's just a common strategy. –  Oct 12 '15 at 18:11
  • Where is this known as a common strategy? – Ed Heal Oct 12 '15 at 18:12
  • The array is a defined size, so how does this work if im using char* arr[40]? – Taylor Oct 12 '15 at 18:13
  • @EdHeal e.g. in many containers of higher level languages, see e.g. http://stackoverflow.com/questions/5232198/about-vectors-growth –  Oct 12 '15 at 18:13
  • I need it to be of type char* array[40], so how do I avoid the char**? – Taylor Oct 12 '15 at 18:15
  • @Taylor "since I cannot be sure how many strings there are." <- that's what you wrote. `strtok()` will just replace delimeters specified by you with `0` bytes and return the pointers to the now split string. You have to store them somewhere. –  Oct 12 '15 at 18:16
  • @Taylor why do you *need* the elements to have exactly 40 bytes? You shouldn't care about their length. –  Oct 12 '15 at 18:17
  • @FelixPalmen - Is not 1.5 the more common value? (i.e. the golden ratio). – Ed Heal Oct 12 '15 at 18:19
  • @EdHeal it might be the "more optimal" value, but more common is 2, probably for the sake of simplicity. (and btw, the golden ratio would be 1.62) –  Oct 12 '15 at 18:20
  • 1. How is it more simple? 2. Evidence for you assumption that 2 is more common? – Ed Heal Oct 12 '15 at 18:21
  • @EdHeal get on someone else's nerves. –  Oct 12 '15 at 18:21
  • @EdHeal haha, how mature, downvoting as a revenge for showing your cluelessness. well, thanks :p –  Oct 12 '15 at 18:22
  • array[40] was defined as a part of my assignment. I have it compiling with the version you did except arr* instead of arr** (it said this is incompatible pointer type) but then I still need to transfer that to my original array – Taylor Oct 12 '15 at 18:23
  • @Taylor, are you sure you weren't given a maximum number of words to split, too? otherwise, this just complicates it .... –  Oct 12 '15 at 18:24
  • @FelixPalmen - I just do not think it is a good answer – Ed Heal Oct 12 '15 at 18:25
  • the max characters are 80 that will be in the line. part of the array can and most of the time will be empty – Taylor Oct 12 '15 at 18:25
  • @Taylor I'm talking about a maximum size of the array. In that case, just declare it as a variable (no need for dynamic allocation) and fill it using `strncpy()` (on the return values of `strtok()`). –  Oct 12 '15 at 18:26
  • @EdHeal and I don't care, because it's the straight forward answer to the initial state of the question. The allocation strategy is a suggestion which is pretty clear from the text. And, if you like it or not, it *is* a very common strategy. –  Oct 12 '15 at 18:28
  • @EdHeal as if there weren't enough comments already, but just to give you a little insight in case you're interested: `2` is the closest approximation of the *golden ratio* in integers. Turns out OP doesn't need dynamic allocation at all, but it still might be valuable for future readers. And to address your first edited comment: It's *always* exponential, no matter what the actual factor is. –  Oct 13 '15 at 07:01
0

If you are concerned about the length of the string,reallocate the size of some dynamically allocated array accordingly.than you can store individual words in another array.check this out :

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

int GetWords(const char *String,char buffer[][255]);

int main(void)
{
    char buffer[30][255];

    const char *sentence = "Hello how are you";

    int num_of_words = GetWords(sentence,buffer);

    for( int n = 0 ; n < num_of_words ; n++ )
    {
        printf("word %d : %s\n" , n+1 , buffer[n]);
        //or do something else
    }

    return 0;
}

int GetWords(const char *String,char buffer[][255])
{
    int x = -1 , y = 0 , z = 0 ;

     size_t len = strlen(String) , n = 0 ;

    for( n = 0 ; n < len ; n++ )
    {
        y++;

        if( String[n] == ' ' /* || String[n] == ',' */ )
        {
            y = 0;
            z = 0;
        }

        if( y == 1 ) x++;

        if( y > 0 )
        {
            buffer[x][z] = String[n];
            z++;
            buffer[x][z] = '\0';
        }
    }

    //return number of words
    return (x+1);
}
machine_1
  • 4,266
  • 2
  • 21
  • 42