-1

I'm creating this function that extracts a word or part of the string from a larger string, it works perfectly but I have to use strcpy to convert it from pointer to array, is it possible to return an array?

if not possible can I work directly with pointers? I mean, using pointers instead of arrays this causes problems with header <string.h> functions ? Or I can use alla function without problem ?

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

char *substr(const char mainstring[], const int cstart, const int clength){
    // printf(" %s \n ", substr("To many Strings", 8,7)); // = Strings
    int main_length = 0;
    int over_length = 0;
    
    main_length = strlen(mainstring); // gets the length of mainstring[]
    over_length = ( main_length - (cstart + clength)); // the value must be greater than -1 and less than the length of the mainstring[]

    
    char *result = malloc(clength+1); // initialize by adding +1 for terminator \ 0
    
    //That must be equal to or greater than 0 and less than the maximum length of the mainstring
    if ( over_length >= 0 && over_length <= (cstart + clength)) { 
    
    strncpy(result, mainstring+cstart, clength); // copies the selected part to result
    strcat(result, "\0"); // add terminator EOS end of string
    
    }else{
    printf("\n Error: Excessive size : %d", over_length); //shows when the condition is not met
    
    }
    return result;
}

int main(){

// use the function substr("String", start, length)

printf(" %s \n ", substr("To many Strings", 8,7)); // = Strings

return 0;
}
ExagonX
  • 141
  • 10
  • 3
    No, you can return a structure that contain arrays, but you cannot return arrays. Also what do you mean by "work directly with pointers"? – MikeCAT Mar 16 '21 at 13:27
  • 3
    You can't return arrays from functions in C. Nor can you pass them as arguments -- your `mainstring` is a pointer not an array despite how it looks. – Paul Hankin Mar 16 '21 at 13:27
  • 3
    Note that `strcat(result, "\0");` is meaningless. `strcat()` will search for `'\0'` before adding things and `"\0"` is a 2-element array `{'\0', '\0'}` (explicitly written `\0` plus automatically added `\0`) that contain zero-character string, so nothing will be added. – MikeCAT Mar 16 '21 at 13:31
  • @MikeCAT I mean, once I have returned the result stored in a pointer, do I have to convert it to array in order to process it or do the functions operate on pointers with no side effects? – ExagonX Mar 16 '21 at 13:31
  • 1
    Replace `strcat(result, "\0");` with `result[clength] = '\0';`. – Ian Abbott Mar 16 '21 at 13:33
  • You are using`malloc()` to produce the pointer to return (returning pointer to non-static local array, which is not done here, is bad), so working with that with `string.h` is fine. Whether side effects exists depends on the functions to use. (`strcat()` may cause side effect, for example) You should do `result[clength] = '\0';` instead of `strcat(result, "\0");`. – MikeCAT Mar 16 '21 at 13:33
  • @IanAbbott Thank you for your suggestion – ExagonX Mar 16 '21 at 13:36
  • Does this answer your question? [Returning an array using C](https://stackoverflow.com/questions/11656532/returning-an-array-using-c) – user14063792468 Mar 16 '21 at 13:40
  • 1
    Probably also worth mentioning in the case of invalid range specification the function still returns `result`, which is now referring to an allocated, but indeterminate region of memory, and the caller has no way of know which is which (the caller cannot "monitor" the error message spewed because of the improper range). Either terminate that region from inception, or possibly better, don't allocate in the first place, and return NULL, which the caller can test, in the case of a bogus range. – WhozCraig Mar 16 '21 at 13:52
  • @WhozCraig Forgive me but I have a hard time following your explanation, could you give me an example? – ExagonX Mar 16 '21 at 16:58
  • 1
    Consider (a) initializing `result` to NULL, and (b) moving the actual `malloc` *inside* the block test for `if ( over_length >= 0....` . Consider how that would change the code, and how the caller now knows if something failed (because NULL was the result, and thus something they can *look for*). – WhozCraig Mar 16 '21 at 17:43
  • @WhozCraig yes right , I, going to made a correction for give a message when the value is not enough to do a correct work, Thank you – ExagonX Mar 16 '21 at 23:17

1 Answers1

1

You cannot return an array as value because in most context an array automatically decays to the pointer to its first element. Thus

return result;

is actually

return &result[0];

which is char* not char[].

There are workarounds described in answers in Returning an array using C. Especially, the one with wrapping an array with struct is interesting.

Btw. Symmetrically, it is not possible to pass an array as a function argument.

When you see

void fun(char arr[N])

it is a syntactic sugar for:

void fun(char *arr)

N is ignored.

Some consider using array arguments as a bad practice. Mostly, because arr is not an array in neither of contexts i.e. sizeof(arr) == sizeof(char*).

Actually, it is difficult to work with arrays:

  • it decays to pointers almost everywhere
  • passing arrays by value would be very costly
  • syntax for pointers to arrays require quite verbose typing
tstanisl
  • 13,520
  • 2
  • 25
  • 40