Home > Back-end >  Not getting output from string array function in c
Not getting output from string array function in c

Time:05-30

I was making a split function in C to use its return value in some programs. But when I checked its value using printf, I discovered that there are some errors but I was unable to fix them myself. I fixed most of the errors I could.

The code I wrote is:

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

char **split(char *token, char *delimiter, int *a[], int *size_of_a) {
    int i = 0;
    char **final_result;
    char *str = strtok(token, delimiter);
    
    while (str != NULL) {
        *a[i] = strlen(str); //maybe one of the errors but I don't know how to fix it
        //even after removing a[i] by backslash and changing it in loop and main, there is still no output received in main
        getch();
        for (int j = 0; j < *a[i]; j  ) { 
            final_result[i][j] = str[j];
        }
        str = strtok(NULL, delimiter);
        i  ;
    }
    *size_of_a = i;
    return final_result;
}

int main() {
    char *parameter_1;
    char *parameter_2;
    int *size_1;
    int size_2;
    
    printf("Enter the token: ");
    scanf("%s", &parameter_1);
    printf("\nEnter the delimiter: ");
    scanf("%s", &parameter_2);
    
    char **result_2 = split(parameter_1, parameter_2, &size_1, &size_2);
    
    printf("\nThe result is:");
    for (int x = 0; x < size_2; x  ) {
        printf('\n');
        for (int y = 0; y < size_1[x]; y  ) {
            printf("%c", result_2[x][y]);
        }
    }
    getch();
    return 0;
}

How can I fix the output error?

CodePudding user response:

There are multiple problems in the code:

  • You do not allocate space for the array of pointers: final_result is uninitialized, storing anything via dereferencing it has undefined behavior, most likely a segmentation fault.

    You should use strcpn() and strspn() to compute the number of tokens, allocate the array with or without an extra slot for a NULL terminator and perform a second phase splitting the tokens and storing the pointers to the array. You might want to store copies of the tokens to avoid modifying the original string that may be constant or go out of scope.

  • printf('\n'); is invalid: you must pass a string, not a character constant.

  • scanf("%s", &parameter_1); also has undefined behavior: you pass the address of a pointer instead of a pointer to an array of char.

Here is a modified version:

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

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

#ifdef _MSC_VER
// define POSIX function strndup if not available
char *strndup(const char *s, size_t n) {
    size_t len;
    for (len = 0; len < n && s[len]; len  )
        continue;
    char *ptr = malloc(len   1);
    if (ptr) {
        memcpy(ptr, s, len);
        ptr[len] = '\0';
    }
    return ptr;
}
#endif

char **split(const char *str, const char *delimiters, int **a, int *size_of_a) {
    int i, count, len;
    char **final_result;
    const char *p;

    // phase 1: count the number of tokens
    p = str   strspn(str, delimiters);
    for (count = 0; *p; count  ) {
        p  = strcspn(p, delimiters);
        p  = strspn(p, delimiters);
    }

    // phase 2: allocate the arrays
    final_result = calloc(sizeof(*final_result), count   1);
    if (a) {
        *a = calloc(sizeof(**a), count);
    }
    if (size_of_a) {
        *size_of_a = count;
    }

    // phase 3: copy the tokens
    p = str;
    for (i = 0; i < count; i  ) {
        p  = strspn(p, delimiters);    // skip the delimiters
        len = strcspn(p, delimiters);  // count the token length
        if (a) {
            (*a)[i] = len;
        }
        final_result[i] = strndup(p, len); // duplicate the token
        p  = len;
    }
    final_result[count] = 0;
    return final_result;
}

// read and discard the rest of the user input line
int flush_input(void) {
    int c;
    while ((c = getchar()) != EOF && c != '\n')
        continue;
    return c;
}

int main() {
    char buf[256];
    char delimiters[20];
    
    printf("Enter the string: ");
    if (scanf("%5[^\n]", buf) != 1)
        return 1;
    flush_input();
    printf("\nEnter the delimiters: ");
    if (scanf("[^\n]", delimiters) != 1)
        return 1;
    flush_input();
    
    int *sizes;
    int count;
    char **array = split(buf, delimiters, &sizes, &count);
    
    printf("\nThe result is:\n");
    for (int x = 0; x < count; x  ) {
        for (int y = 0; y < sizes[x]; y  ) {
            putchar(array[x][y]);
        }
        printf("\n");
    }
    getchar();
    return 0;
}
  •  Tags:  
  • c
  • Related