Search code examples
cstringstring-length

string of undetermined length c


Hi I was trying to create an array of string of an undetermined length in c. This is my code :

    int main()
    {
        int lineCount=linesCount();
        char text[lineCount][10];
        printf("%d",lineCount);
        FILE *  fpointer = fopen("test.txt","r");
        fgets(text,10,fpointer);
        fclose(fpointer);
        printf("%s",text);
        return 0;
    }

I would like to replace 10 in

    char text[lineCount][10];

My code reads out a file I already made the amount of lines dynamic. Since the line length is unpredictable I would like to replace 10 by a something dynamic. Thanks in advance.


Solution

  • To do this cleanly, we want a char * array rather than an 2D char array:

    char *text[lineCount];
    

    And, we need to use memory from the heap to store the individual lines.

    Also, don't "hardwire" so called "magic" numbers like 10. Use an enum or #define (e.g) #define MAXWID 10. Note that with the solution below, we obviate the need for using the magic number at all.

    Also, note the use of sizeof(buf) below instead of a magic number.

    And, we want [separate] loops when reading and printing.

    Anyway, here's the refactored code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int
    linesCount(void)
    {
    
        return 23;
    }
    
    int
    main(void)
    {
        int lineCount = linesCount();
        char *text[lineCount];
        char buf[10000];
    
        printf("%d", lineCount);
    
        // open file and _check_ the return
        const char *file = "test.txt";
        FILE *fpointer = fopen(file, "r");
        if (fpointer == NULL) {
            perror(file);
            exit(1);
        }
    
        int i = 0;
        while (fgets(buf, sizeof(buf), fpointer) != NULL) {
            // strip newline
            buf[strcspn(buf,"\n")] = 0;
    
            // store line -- we must allocate this
            text[i++] = strdup(buf);
        }
    
        fclose(fpointer);
    
        for (i = 0;  i < lineCount;  ++i)
            printf("%s\n", text[i]);
    
        return 0;
    }
    

    UPDATE:

    The above code is derived from your original code. But, it assumes that the linesCount function can predict the number of lines. And, it doesn't check against overflow of the fixed length text array.

    Here is a more generalized version that will allow an arbitrary number of lines with varying line lengths:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int
    main(void)
    {
        int lineCount = 0;
        char **text = NULL;
        char buf[10000];
    
        // open file and _check_ the return
        const char *file = "test.txt";
        FILE *fpointer = fopen(file, "r");
        if (fpointer == NULL) {
            perror(file);
            exit(1);
        }
    
        int i = 0;
        while (fgets(buf, sizeof(buf), fpointer) != NULL) {
            // strip newline
            buf[strcspn(buf,"\n")] = 0;
    
            ++lineCount;
    
            // increase number of lines in array
            text = realloc(text,sizeof(*text) * lineCount);
            if (text == NULL) {
                perror("realloc");
                exit(1);
            }
    
            // store line -- we must allocate this
            text[lineCount - 1] = strdup(buf);
        }
    
        fclose(fpointer);
    
        // print the lines
        for (i = 0;  i < lineCount;  ++i)
            printf("%s\n", text[i]);
    
        // more processing ...
    
        // free the lines
        for (i = 0;  i < lineCount;  ++i)
            free(text[i]);
    
        // free the list of lines
        free(text);
    
        return 0;
    }