Search code examples
cstringdynamic-memory-allocationrealloc

Trying to take multiple string inputs


Practice.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define ARR 32

int main(void){

  int MEM=64;
  char arr[ARR],*p=(char *)calloc(MEM,(sizeof(char))),*q=NULL;
  int i=0,j=1;

  printf("\nEnter String : ");

  while(j){

    scanf(" %[^\n]s " ,arr);

    if(j==1)
      strcpy(p,arr);
    else
      strcat(p,arr);


    if((j*ARR)==MEM){
      MEM=MEM+(j*ARR);
      q=realloc(p, MEM);
      if(!(q)){
        printf("\nNOT ENOUGH MEMORY\n");
        goto END;
      }
      p=q;
    }


    for(i=0;i<(strlen(arr));++i){
      if(arr[i]=='\n')
        break;
    }


    if(arr[i]=='\n')
      break;


    ++j;
  }

  printf("\n %s\n",p);


  END: free(p);p=NULL;q=NULL;

  return 0;
}

I am trying to get multiple string inputs.

I am using scanf(" %[^\n]s",arr); to take the input instead of fgets(arr,ARR,stdin);, because with fgets the program execution stops as soon as I hit ENTER key. But with scanf(" %[^\n]s",arr); the program is unable to get out of the while() loop even after entering \n.

I would like to know the mistake or mistakes I have made while writing the code.


Solution

  • One mistake is:

    for(i=0;i<(strlen(arr));++i){
      if(arr[i]=='\n')
        break;
    }
    

    Looking earlier in you code you have:

    scanf(" %[^\n]s " ,arr);
    

    The [^\n] prevents any newlines \n from being contained in arr. So your loop that looks for (arr[i]=='\n') will never find any. Your next bit of code continues looking for non-existent newlines:

    if(arr[i]=='\n')
      break;
    

    This last break also breaks out of your outer loop preventing you from asking for further input on finding a newline (which it shouldn't). Fix these issues and it should get much further allowing you to enter multiple items.


    Edit:

    With a bit of effort looking at what you were doing, I now have it taking multiple input and reallocating as necessary. The strings are all concatenated and printed at the end. It could still stand a bit of work, but this should give you a few hints:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #define ARR 32
    
    int main (void) {
    
        int MEM = 64;
        char arr[ARR], *p = (char *) calloc (MEM, (sizeof (char))), *q = NULL;
        int i = 0, j = 1;
    
    
        while (j) {
    
            printf ("\nEnter String : ");
            scanf (" %[^\n]s ", arr);
            printf (" you entered (arr): %s\n", arr);
            if (strcmp (arr, "q") == 0) {
                printf ("\n  'q' entered, exiting.\n\n"); // provide for exit if `q` entered
                break;
            }
    
            if (j == 1)
                strcpy (p, arr);
            else
                strcat (p, arr);
    
            if ((j * ARR) == MEM) {
                MEM = MEM + (j * ARR);
                q = realloc (p, MEM);
                if (!q) {
                    printf ("\nNOT ENOUGH MEMORY\n");
                    goto END;
                }
                else
                    printf ("\nMemory Reallocation - succeeded.\n");
                p = q;
            }
            ++j;
        }
    
        printf (" %s\n", p);
    
    END:
        if (p) free (p);  /* always test pointer before calling free */
        p = NULL;
        q = NULL;
    
        return 0;
    }
    

    output:

    ./bin/me
    
    Enter String : fishinsea
      you entered (arr): fishinsea
    
    Enter String : alligators
      you entered (arr): alligators
    
    Memory Reallocation - succeeded.
    
    
    Enter String : really_big_mosters
      you entered (arr): really_big_mosters
    
    Enter String : SuperSnake_Prudhome
      you entered (arr): SuperSnake_Prudhome
    
    Memory Reallocation - succeeded.
    
    Enter String : 8_puppies
      you entered (arr): 8_puppies
    
    Enter String : q
      you entered (arr): q
    
      'q' entered, exiting.
    
    fishinseaalligatorsreally_big_mostersSuperSnake_Prudhome8_puppies