2

I am building a cipher program but i can't figure out how to return an array of char[] my cipher method

char *cipherinput(int ciphercount){
int i=0;
char *cipher[MAX_CIPHER_SIZE];


if(ciphercount>=2){
    printf("Enter the Cipher!\n");
    //loop through and add
    for(i=0;i<ciphercount;i++){
        scanf(" %c", cipher[i]);
    }
}

   return cipher;
}

my main method has

#define MAX_CIPHER_SIZE 16
#define MAX_TEXT_SIZE 256
int main()
{
   int ciphercount=0, textcount=0,i=0,j=0,k=0;
   int *cipher_, *text_, N=0,N_;

   printf("Enter size of Cipher!\n");
   scanf("%d", &ciphercount);

   if(ciphercount>=2){
    cipher_ = cipherinput(ciphercount);
   }
   else{
     printf("Start again / Cipher size should be greater or equal to 2\n");
     main();
   }
   return 0;
 }

I've tried several methods such as char** (string) with no success.

3
  • 1
    first off - this char *cipher[MAX_CIPHER_SIZE]; makes an array of strings. I dont think this is what you want Commented Mar 6, 2018 at 21:54
  • you can't return arrays in c. If you really want to, you'll have to wrap it in a struct Commented Mar 6, 2018 at 21:54
  • If you return an array you need to indicate how long it is, or have some kind of convention like a NULL pointer as the last element in the array. Commented Mar 6, 2018 at 21:55

3 Answers 3

4

You are returning a pointer to stack memory, which is undefined behavior. Most likely your returned string will be corrupted shortly after the function returns or after the invocation of another function.

This is closer to what you want:

char* cipherinput(int ciphercount) {
    int i=0;
    char cipher[MAX_CIPHER_SIZE+1]; // +1 to guarantee null termination.
    cipher[0] = '\0';

    if(ciphercount>=2){
        printf("Enter the Cipher!\n");
        //loop through and add
        for(i=0;i<ciphercount;i++){
            scanf(" %c", cipher[i]);
        }
        cipher[ciphercount] = '\0'; // null terminate
    }

    return strdup(cipher);   // this is the same as ptr=malloc(strlen(cipher+1)) followed by strcpy(ptr,cipher)
}

The function returns a copy of the string the user typed in. The caller of this function is expected to invoke free on the returned pointer after it's done with it. If ciphercount < 2, the function will return an empty string.

Sign up to request clarification or add additional context in comments.

1 Comment

why is it returning an empty string
1

Normal way 1, Allocate result in function and return it

    char *cipherinput(int ciphercount){
      char *cipher = malloc(MAX_CIPHER_SIZE);
...
      return cipher;
    }

Note that your caller will have to free the result

Normal way 2, Caller creates and passes result buffer

void cipherinput(int ciphercount, char * cipher){
 ....
}

caller goes

    char cipher[MAX_CIPHER_SIZE];
    cipherinput(x, cipher);

Normal way #3. HAve fixed static buffer in function. NOTE THIS IS NOT rentrant or thread safe.

char *cipherinput(int ciphercount){
  static char cipher[MAX_CIPHER_SIZE];
  .....
  return cipher;
}

In general #2 is probably best since you are less likely to leak

Comments

1

If you want to use char *cipher outside your function

char *cipherinput(int ciphercount){
     int i=0;
     char *cipher[MAX_CIPHER_SIZE];
     //...
     return *cipher;
}

You need to allocate memory for your cipher buffer. Your cipher[MAX_CIPHER_SIZE] will not exist once the cipherinput function returns. This is the most common approach:

 char* cipherinput(int ciphercount) {
        // ...
        char *cipher = malloc( sizeof(char) * (MAX_CIPHER_SIZE+1) ); // +1 to guarantee null termination.

        //...
        return cipher;
    }

This approach requires you to remember to free the memory allocated for cipher once you do not needed.

In embedded systems you may want to avoid memory allocation, since allocation and deallocation may not be timely operation. In such case, the best approach is to pass a buffer to your function:

char cipher[MAX_CIPHER_SIZE+1];    // buffer outside the function
cipherinput(ciphercount, cipher);  // function call

Function implementation:

void cipherinput(int ciphercount, char * cipher){
 // access elements of cipher buffer via cipher[i]);
 // ...
}

2 Comments

sizeof(char) is always one by definition.
@AndrewHenle Thank you. Good comment! I like to use sizeof(char) since it underlines the type of variables which I want to keep in the memory.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.