0

I am new to C, and I find it too hard to convert my program from using static arrays to using dynamic allocated arrays.

This is my 3rd program (that count words etc. form a .txt file).

So what changes do I have to do to use dynamic arrays in my program instead of static arrays?

This is a part of my code:

int main(int argc, char *argv[]) { 
 FILE *myinput; 
 int count=0, a, userchoice,i=0, wrd,chrct,dfw,j,b,k;
 char arr[100][50], name[0][50];

  printf("Ender the name of the file you want to open: ");
  scanf("%s", name[0]);
  if((myinput = fopen(name[0], "r"))==NULL)
  {
    printf("Failed to open the file!");
    exit(1);
  }
  else
  {
printf("Reading %s.. Done!\n\n", name[0]);
printf("%s contein: ", name[0]);
  }
  while(wrd > 0)
    {
        wrd = fscanf(myinput, "%s",arr[i]);
        i++; //counting words in a line from txt file.
    }
  wrd = i;
    for(i = 0; i < wrd - 1; i++)
    {
        printf("%s ", arr[i]);
    }
printf("\n");
 while(userchoice!=5)
 {
    switch(userchoice=choice())  //choice() is a function just with a scanf.
      {



        case 1: wrd=countwords(myinput); break;
        case 2: chrct=coutnchar(myinput); break;
        case 3: dfw=diffrentwords(wrd,arr); break; 
        case 4: istograma(wrd,arr); break;
        default: break;
      }
 }
 results(wrd,chrct,dfw,myinput,arr,wrd);
 fclose(myinput); 
 return 0; 
}

Here are some functions:

int choice(){
    int choice;
    printf("\n1: count words \n2: count characters \n3: count different words \n4: Istogramma\n5: Save and exit\n");
    printf("enter choice:\n");
    scanf("%d", &choice);
    return choice;
}

Here is the histogram function:

istograma(int wrd, char arr[100][50]){
    int j, i = 0, len;

    for(i = 0; i < wrd - 1; i++){
      printf(" %s ",arr[i]);
      len=strlen(arr[i]);
      for(j=0; j<len; j++){
        printf("*");
      }
      printf("\n");
    }
}
user3623727
  • 7
  • 1
  • 5

3 Answers3

1

char name[0][50]; do you mean [1][50]?

for char arr[100][50]:

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

int main(void)
{
    char (*arr)[50];
    int i;

    arr = malloc(sizeof(*arr) * 100);
    if (arr == NULL) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    for (i = 0; i < 100; i++)
        strcpy(arr[i], "test");
    for (i = 0; i < 100; i++)
        printf("%s\n", arr[i]);
    free(arr);
    return 0;
}   
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
1

Debugging your program directly would not help you much, IMHO.

I think that you need an example to get you started.

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

#define N 4

int main() {
    int a[N]; //I am a static array,
    // with four uninitialized elements.

    int i;

    for(i = 0; i < N; ++i)
        a[i] = i;

    // a[0] = 0, a[1] = 1, a[2] = 2, a[3] = 3.
    // Index starts from 0 and ends at N - 1 = 4 - 1 = 3.

    // print the array
    for(i = 0; i < N; ++i)
        printf("%d ", a[i]);
    printf("\n");

    // Now let's use a dynamic array

    // this will be the pointer to the array
    int* a_dyn;

    // here we allocate memory dynamically
    // how much memory? As many elements we need,
    // multiplied by the size of every element.
    // Here we need N elements, of type int,
    // thus N * sizeof(int)
    a_dyn = malloc(N * sizeof(int));

    // fill the array (like the static case)
    for(i = 0; i < N; ++i)
        a_dyn[i] = i;

    // print the array (like the static case)
    for(i = 0; i < N; ++i)
        printf("%d ", a[i]);
    printf("\n");

    // DO NOT FORGET TO FREE YOUR DYNAMIC MEMORY
    free(a_dyn);

    return 0;
}

Study the example and then ask if needed.

Then, try to debug your code and report back if needed.

Hint:

enter image description here

This picture is actually what you want to create.

The 1D array at the left is the array that will hold your strings, which are of type char*.

The right 1D arrays, are the actual strings, with every cell holding a character.

So, fore example, if you had stored the string "sam" as your firt string, then you would have these:

a[0][0] = 's'
a[0][2] = 'a'
a[0][2] = 'm'
a[0][3] = '\0' <------Never forget the null terminator

For more, click here.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
0

You should use malloc(). To resize the array you should use realloc().

Here is an example. With the reference of your code.

   char **arr, **temp;
   char string[50];
   int i;
   arr=NULL;
   temp=NULL;
   i=0;
   while(1)
   {
     wrd = fscanf(myinput, "%s",string);
     if(!(wrd>0))
     {
       break;
     }
     temp=(char **)realloc(arr,sizeof(char *)*(i+1));//With some enhancement
     //This increses size of the arr pointer with retaining the data and assigns it to "temp" pointer. Realloc copies data of arr in different memory having (i+1) size and stores it's reference in "temp".
     arr=temp;
     //we store the referene of temp in arr.
     arr[i]=(char *)malloc(sizeof(char)*(strlen(string)+1));
     //It allocates memory to the the arr[i]. You may compare it with your 2-d array but in dynamic array every row may have different size. We also save memory by doing this.
     strcpy(arr[i],string);
     //Copies "string"
     i++; //counting words in a line from txt file.
   }
वरुण
  • 1,237
  • 3
  • 18
  • 50
  • Can you comment what are doing at last 5 lines. If you do it I will accept your answer! – user3623727 May 12 '14 at 12:52
  • Do not cast what `malloc` returns. http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – gsamaras May 12 '14 at 12:58
  • @user3623727 since you selected this answer, this means that you are going to use `realloc`? If you need to use `realloc`, it would probably be far better to use a `simple linked list`. – gsamaras May 12 '14 at 13:18
  • @user3623727, just another tip, using `realloc` in every step of the `while` loop is a bad idea, in terms of efficiency. It would be faster to use a `list`, or even to count the lines of the file, allocate your array and then read again the file, in order to fill the array. – gsamaras May 12 '14 at 13:47
  • @G.Samaras I think you are right but for my knowledge I prefer this answer! I dont have much time to learn something new now but thank you! – user3623727 May 12 '14 at 14:54
  • @user3623727, I do not care which answer you will accept and upvote. I am telling you so that you will have that in mind too, since Varun doesn't really say anything. You are welcome. :) – gsamaras May 12 '14 at 15:05