2

I would like to know what would be the equivalent for filling an array like we do in Python, but in C.

Python example code:

arrayname=[0]*10
randomtextvar="test_text"
for i in range(10):
    arrayname[i]=randomtextvar
for k in range(10):
    print(arrayname[k]+" "+str(k)+ " position")

I haven't find an solution for this, I don't really understand how to set value to a string (char) array position (in C).

EDIT:

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

int main() {
    int c = 0;
    char arr[256];
    fgets(arr, 256, stdin);
    char spl[] = " ";
    char *ptr = strtok(arr, spl);
    while (ptr != NULL) {
        ptr = strtok(NULL, spl);
        // HERE I WANT TO ADD THE ptr value to a new array of strings
        c++;
    }
    return 0;
}
Grismar
  • 27,561
  • 4
  • 31
  • 54
joig
  • 43
  • 4
  • 1
    What does 'valorize' mean? – darkspine Jan 07 '21 at 02:33
  • I meant set value, translating mistake, already edited, sorry. – joig Jan 07 '21 at 02:35
  • You want the `arrayname` to be an array of strings? – darkspine Jan 07 '21 at 02:36
  • 2
    Please show as much of the code as you already know how to do. It's not clear what exactly you don't understand. Do you want to make copies of the string or reference the same string? Do you know how to declare an array? Do you know about pointers? Do you know how to copy strings? – kaylum Jan 07 '21 at 02:37
  • @darkspine Exactly, I want the `arrayname` to be an array of strings. – joig Jan 07 '21 at 02:42
  • 4
    And searching for "C array of strings" didn't come up with any useful info? Such as [this](https://stackoverflow.com/questions/1088622/how-do-i-create-an-array-of-strings-in-c) and [this](https://stackoverflow.com/questions/15161774/how-to-create-an-array-of-strings-in-c) and [this](https://stackoverflow.com/questions/21023605/initialize-array-of-strings) etc. – kaylum Jan 07 '21 at 02:43
  • @kaylum Edited. – joig Jan 07 '21 at 02:46
  • @kaylum Well I looked up for a while before posting this, but I didn't find something similar, I tried to implement some examples I saw but they didn't work for me, probably I'm the one who is not doing it properly tho. – joig Jan 07 '21 at 02:54
  • 1
    You can do: `char *string_array[10]; int i = 0; ... string_array[i++] = strdup(ptr);`. Note that `strdup` allocates dynamic memory so you need to `free` it when no longer needed. Also, need to ensure array is not overflowed. – kaylum Jan 07 '21 at 02:56
  • @kaylum I hadn't heard about `strdup` before, it worked for me. I can't upvote, but thanks, really appreciate it. :) – joig Jan 07 '21 at 03:26

1 Answers1

1

You are doing strtok before the while loop and immediately at the start. So, you are trashing the first token on the line.

kaylum pointed out a simple way to save the strings into a fixed array using strdup.

But, I suspect you'd like something as flexible as what python is doing. So, the array of strings can be dynamically grown as you process many input lines using realloc.

Also, in addition, it's sometimes nice to have the last array element be NULL [just like argv].

Here's some refactored code. I've annotated it to explain what is going on:

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

int
main(void)
{
    char *ptr;
    char *bp;
    const char *spl = " \n";
    char buf[256];
    char **arr = NULL;
    size_t arrcnt = 0;
    size_t arrmax = 0;

    // read in all input lines
    while (1) {
        // get next input line -- stop on EOF
        ptr = fgets(buf,sizeof(buf),stdin);
        if (ptr == NULL)
            break;

        // parse the current line
        bp = buf;
        while (1) {
            // get next token on the current line
            ptr = strtok(bp,spl);
            bp = NULL;

            // stop current line if no more tokens on the line
            if (ptr == NULL)
                break;

            // grow the string array [periodically]
            // NOTE: using arrmax cuts down on the number of realloc calls
            if (arrcnt >= arrmax) {
                arrmax += 100;
                arr = realloc(arr,sizeof(*arr) * (arrmax + 1));
                if (arr == NULL) {
                    perror("realloc/grow");
                    exit(1);
                }
            }

            // add current string token to array
            // we _must_ use strdup because when the next line is read any
            // token data we had previously would get overwritten
            arr[arrcnt++] = strdup(ptr);

            // add null terminator just like argv -- optional
            arr[arrcnt] = NULL;
        }
    }

    // trim the array to the exact number of elements used
    arr = realloc(arr,sizeof(*arr) * (arrcnt + 1));
    if (arr == NULL) {
        perror("realloc/trim");
        exit(1);
    }

    // print the array
    for (char **av = arr;  *av != NULL;  ++av)
        printf("%s\n",*av);

    // free the array elements
    for (char **av = arr;  *av != NULL;  ++av)
        free(*av);

    // free the array
    free(arr);

    // reset counts and pointer
    arrmax = 0;
    arrcnt = 0;
    arr = NULL;

    return 0;
}
Craig Estey
  • 30,627
  • 4
  • 24
  • 48