简体   繁体   中英

Return Array of Strings with String Input

I'm trying to take a string and break it into "word" components and store that in an array of strings. "Hello my name is Bill." should give back a char** with elements, "Hello", "my", "name", "is", and "Bill."

My code will compile however I keep encountering a runtime error (I don't get warnings anymore and my debugger gdb doesn't work)>

I'm running on minGW on Window 8.

#include <stdio.h>
#include <stdlib.h>

char** words(char* string)
{
    int i = 0;
    int j = 0;
    int k =0;
    int count = 0;

    char** stringArray = (char**) malloc(sizeof(char)*30*30);

    while( string[i] != '\0' )
    {
        if(string[i] != ' ')
        {
            j =0;
            while(string[i+j+1] != ' ')
            {
                j++;
            }
            i = i+j;
            for(k=0; k<=j; k++)
            {
                stringArray[count][k] = string[i+k];
            }
            count++;        
        }
        i++;
    }

    return stringArray;

}   
int main()
{   
    char message[20] = "abcd efgh ijkl mno";

    char** wordArray = words(message);

    printf("%c\n\n", wordArray[0][0]);

    int i =0;
    while(wordArray[i])
    {
        printf("%s\n", wordArray[i]);
        i++;
    }
    printf("\nThe problem is not with the words function");

    return 0;
}

There are couple of issues that have been mentioned in the comments. The allocation should look something like:

#include <ctype.h>    // for isspace()    

#define MAXSTRLEN 30  // using a symbolic constant

char **stringArray;
int i, j, k;

stringArray = malloc(sizeof(char*) * MAXSTRLEN); // don't cast from malloc
for (i = 0; i < 30; ++i) {
  stringArray[i] = malloc(sizeof(char) * MAXSTRLEN);
}
// TODO error checking: malloc could return NULL

while copying the substrings would look like:

i = 0;
j = 0;
while( string[i] != '\0')  // go through the whole string
{
    while (string[i] != '\0' && isspace(string[i])) {
     i++; // skip whitespaces
    }

    k = 0;
    while (string[i] != '\0' && !isspace(string[i])) { // copy word until whitepace or end of string
        stringArray[j][k++] = string[i++];
    }
    stringArray[j][k] = '\0'; // EOS !!!
    j++;
}

and printing (j is number of words actually read):

for (i = 0; i < j/*30*/; ++i) {  // (!) how to print
    printf("%s\n", stringArray[i]);
}

And, yes strtok would also do the job.

In words() you're assigning values to stringArray as a two-dimensional array, and in main() you're reading values from it as an array of pointers. Those are not the same thing.

So you need to change it so that you're consistently treating it as a 2D array, or so that you're consistently treating it as an array of pointers ( char* to be exact). Either will work... see the comments above for elaboration.

This code is all wrong.

char** stringArray = (char**) malloc(sizeof(char)*30*30);

First of all, sizeof(char) is always one, second, you don't need to cast a void. So:

char **stringArray = malloc(30 * 30);

But that doesn't make any sense because it's an array of char * , so you should allocate in terms of that:

char **stringArray = malloc(sizeof(char *) * 30);

Or even better:

char **stringArray = malloc(sizeof(*stringArray) * 30);

So now you have an array with 30 char * , but each of those is not initialized, so you need to do that:

for (i = 0; i < 30; i++)
    stringArray[i] = malloc(sizeof(**stringArray) * 30);

If you don't do that, you can't access stringArray[count][k].

And then you assume the last element in the array is NULL, but you never set it, so you either do stringArray[count] = NULL at the end of words(), or you do calloc() instead of malloc().

I'm not analyzing the code beyond that; it's just all wrong.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM