Thread: split char array, store and return it

  1. #1
    Registered User
    Join Date
    Jul 2020
    Posts
    2

    Lightbulb split char array, store and return it

    Hi, i'm trying to do a function to split a char string received by parameter letter-by-letter, store, and return it. I writed this code, its working but i'm using two functions to do that, and i wanna do everything in one function, but using the same code(or almost).

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    //this will add a char to string(strcat() only accept same type :( )
    void add_char_to_s(char text[], char ch){
        size_t sz = strlen(text);
        text[sz] = ch;
        text[sz + 1] = '\0';
    }
    
    //now lets split received word by spaces and return it
    static char *xplode_string(char word[])
    {
        static char t[sizeof(*word)] = "";
        
        for (int i=0; i < strlen(word); i++)
        {
            add_char_to_s(t, word[i]);
            strcat(t, " ");
        }
     
        return t;
    }
    
    
    int main() {
        
        //this will print P a o l a!
        printf("%s", xplode_string("Paola!"));
        
        return 0;
    }

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,092
    This is wrong:
    Code:
    static char t[sizeof(*word)] = "";
    word is a pointer to char, so sizeof(*word) is equal to 1. Hence, t is an array of char that is only large enough to store an empty string.

    If I understand correctly, you want "Paola!" to result in "P a o l a !" (not "P a o l a!" as your comment indicated). So, with a string of length 6, the result string is of length 6*2-1=11. Hence, I would suggest:
    Code:
    size_t word_len = strlen(word);
    char *result = malloc((word_len > 0) ? (word_len * 2) : 1);
    if (word_len == 0)
    {
        result[0] = '\0';
        return result;
    }
    The reason why I don't subtract 1 is that you need to account for the terminating null character. There's no point dealing with an empty string as it differs from the length*2-1 pattern, so I check for it early then return. Of course, the downside of using malloc is that after you return the result, the caller is responsible for freeing the memory, so you shouldn't call it within printf like you're doing now. Rather, store the result in a pointer and then pass that pointer to printf.
    Quote Originally Posted by paola
    I writed this code, its working but i'm using two functions to do that, and i wanna do everything in one function, but using the same code(or almost).
    There's no problem using two functions. What I am more concerned about is that how you're doing the appending with the second function is inefficient: you compute the length of the current result string, and then you append from there; the same "keep finding the end then appending" happens with strcat. This is a waste of time when you can just keep track of the end of the current result string and append from there. For example:
    Code:
    for (size_t i = 0; i < word_len; i++)
    {
        result[i * 2] = word[i];
        result[i * 2 + 1] = ' ';
    }
    result[word_len * 2 - 1] = '\0'; // overwrite the last space
    Incidentally, this eliminates the reason for the second function.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jul 2020
    Posts
    2
    Quote Originally Posted by laserlight View Post
    This is wrong:
    Code:
    static char t[sizeof(*word)] = "";
    word is a pointer to char, so sizeof(*word) is equal to 1. Hence, t is an array of char that is only large enough to store an empty string.

    If I understand correctly, you want "Paola!" to result in "P a o l a !" (not "P a o l a!" as your comment indicated). So, with a string of length 6, the result string is of length 6*2-1=11. Hence, I would suggest:
    Code:
    size_t word_len = strlen(word);
    char *result = malloc((word_len > 0) ? (word_len * 2) : 1);
    if (word_len == 0)
    {
        result[0] = '\0';
        return result;
    }
    The reason why I don't subtract 1 is that you need to account for the terminating null character. There's no point dealing with an empty string as it differs from the length*2-1 pattern, so I check for it early then return. Of course, the downside of using malloc is that after you return the result, the caller is responsible for freeing the memory, so you shouldn't call it within printf like you're doing now. Rather, store the result in a pointer and then pass that pointer to printf.

    There's no problem using two functions. What I am more concerned about is that how you're doing the appending with the second function is inefficient: you compute the length of the current result string, and then you append from there; the same "keep finding the end then appending" happens with strcat. This is a waste of time when you can just keep track of the end of the current result string and append from there. For example:
    Code:
    for (size_t i = 0; i < word_len; i++)
    {
        result[i * 2] = word[i];
        result[i * 2 + 1] = ' ';
    }
    result[word_len * 2 - 1] = '\0'; // overwrite the last space
    Incidentally, this eliminates the reason for the second function.

    THX! And I turn my static function into non-static, and it still works! in the future ... can the fact that this function is not static maybe cause a headache?
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    
    char *split_string(char word[])
    {
    
    
        size_t word_len = strlen(word);
        char *result = malloc((word_len > 0) ? (word_len * 2) : 1);
        if (word_len == 0)
        {
            result[0] = '\0';
            return result;
        } else
        {
            for (size_t i = 0; i < word_len; i++)
            {
                result[i * 2] = word[i];
                result[i * 2 + 1] = ' ';
            }
            result[word_len * 2 - 1] = '\0';
        }
    
    
        return result;
    }
     
    int main() {
         
        //this will print P a o l a !
        printf("%s", split_string("Paola"));
         
        return EXIT_SUCCESS;
    }

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,092
    You're welcome.

    Quote Originally Posted by paola
    And I turn my static function into non-static, and it still works! in the future ... can the fact that this function is not static maybe cause a headache?
    Declaring a function static affects the linkage of its name. That is, instead of the name referring to that function in all translation units (external linkage, which is the default for functions), it only refers to that function that translation unit (internal linkage). A translation unit is a source file + all its included headers (directly or indirectly), so removing the static keyword is only an issue if you have more than one source file. In such cases, you want helper functions that are just implementation detail to have internal linkage so that the names cannot conflict with names declared elsewhere, whereas you want functions that are used in multiple source files to have external linkage, e.g., the interface functions of a library, if you were writing one.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Store 16 bit words in char array?
    By Prediluted in forum C++ Programming
    Replies: 20
    Last Post: 06-03-2011, 01:21 PM
  2. How to store a char array into another char array?
    By DaNxTh3xMaNx in forum C Programming
    Replies: 4
    Last Post: 11-12-2010, 10:28 AM
  3. Howto? split and use a char array
    By djnicovski in forum C++ Programming
    Replies: 18
    Last Post: 07-23-2010, 11:18 PM
  4. Replies: 3
    Last Post: 11-17-2008, 12:36 PM
  5. parse/split a string and store it in variables
    By StRiKeFoRcEnOoB in forum C++ Programming
    Replies: 11
    Last Post: 07-22-2003, 09:58 AM

Tags for this Thread