How to "break" a pure C string to assign the parts to other variables?

Asked

Viewed 1,195 times

-1

I’m doing a thing for college and I’m lost to use C because I learned to code in Python. It’s a simple question: If I have a str string, how can I "break it" into another 3 to assign to three different variables?

Example:

str[ ] = "Bom dia pessoal"; 

str1[ ] = "Bom";  
str2[ ] = "dia"; 
str3[ ] = "pessoal"

I tried using Strtok(), but I was only able to use it to print the separate strings in the terminal, I did not store the parts in other variables. The charitable soul who will help me should bear in mind that, as I am a son of Python, I do not master 100% pointers.

  • How many percent would you say you know about pointers?

  • 50%. I understood the thing of dealing with memory, ma all very theoretical. I tried to write a function that made this separation, but I can’t think of a way to Return a string.

2 answers

1


There are lots of ways to "break" a string in C, more robust, less robust, with or without dynamic allocation, but I’ll take exactly what I said:

I tried to use the strtok(), but I was only able to use it to print the separate strings on the terminal

You can do it with strtok and it’s even simpler because part of the job is already done.

Break - Split with array allocated in Stack

Using a two-dimensional stack array you can split by slightly changing the example of documentation:

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

int qtd_espacos(char *str){
    int espacos = 0;
    while(*str){
        if (*str == ' '){
           espacos++;
        }
        str++;
    }
    return espacos;
}

int main () {
    char str[] = "Bom dia pessoal";

    //quebrar - split da string
    int qtd_strings = qtd_espacos(str) + 1, i = 0;
    char strings[qtd_strings][strlen(str)];
    char *pch = strtok (str," ");
    while (pch != NULL){
        strcpy(strings[i++], pch); //copiar cada string para a posição correta
        pch = strtok (NULL, " ");
    }

    //mostrar cada uma
    for (i = 0;i < qtd_strings;++i){
        printf("%s\n", strings[i]);
    } 

    //ou seguindo o seu exemplo
    printf("%s\n%s\n%s\n", strings[0], strings[1], strings[2]);
    return 0;
}

Check it out at Ideone

Essentially the only thing I’ve done the most about documentation is to copy each string to the right location through the strcpy.

In order to preallocate the right space for the strings I counted how many spaces there are to know how many strings will be created. Actually the amount of spaces + 1 may not directly equal the number of strings, if there are spaces followed, but if so the number of strings will be lower and so it won’t make much difference.

At the end of the code the string was broken to an array of strings, and therefore at the position 0 has the first word in the position 1 the second, and so on. Therefore str1 in the question amounts to strings[0], the str2 to strings[1], etc..

Break - Split with array allocated on Heap

To complement a little, I also show a way to break using heap and respective malloc. In many cases this will seem more natural as everything can now be done within a function and the resulting string array can be returned. How we have the function realloc it is also no longer necessary to count the spaces initially, as you can increase the string array each time you catch a new one.

Example:

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

char** split(char *str, int *qtd){
    *qtd = 0;
    int i = 0;
    char **strings = NULL, *pch = strtok (str," ");
    while (pch != NULL){
        strings = realloc(strings, sizeof(char*) * (*qtd + 1));
        strings[i] = malloc(strlen(pch) + 1); // + 1 para o terminador
        strcpy(strings[i++], pch);
        pch = strtok (NULL, " ");
    }

    return strings;
}

int main () {
    char str[] = "Bom dia pessoal";

    int qtd_strings, i;
    char **strings = split(str, &qtd_strings); //chamar o split e obter as strings
    for (i = 0;i < qtd_strings;++i){
        printf("%s\n", strings[i]);
    }

    //mostrar cada uma
    for (i = 0;i < qtd_strings;++i){
        printf("%s\n", strings[i]);
    }

    //ou seguindo o seu exemplo
    printf("%s\n%s\n%s\n", strings[0], strings[1], strings[2]);
    return 0;
}

See also on Ideone

Note that the break function receives a pointer to an integer called qtd. This is because you need to know how many strings were created in split, otherwise we cannot use them. And since there is already the return of the string array then the quantity could not be returned and the function changes the value of this pointer directly.

In this version whenever you no longer need the strings you must release them using free, otherwise may have memory leaks.

0

I’m assuming the scenario would be the same as example

#include<stdio.h>
#include<string.h>
int main(){

    char str[] = "Bom dia pessoal";
    char *str1, *str2, *str3;
    str1 = strtok(str, " ");
    str2 = strtok(NULL, " ");
    str3 = strtok(NULL, " ");
    printf("Primeira variavel: %s\nSegunda variavel: %s\nTerceira variavel: %s", str1, str2, str3);
    return 0;
}

Working example Ideone

  • Thanks man! It works perfectly, but by chance it would be possible to declare an array pointer? type char *str[40];

Browser other questions tagged

You are not signed in. Login or sign up in order to post.