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");
    }
}
5
  • 1
    Replace each [N] with a malloc... Commented May 12, 2014 at 12:01
  • 1
    With the declaration char ..., name[0][50] you declare an array of size zero. So using even name[0] is out of bounds of the array. Commented May 12, 2014 at 12:01
  • I think you need a vector<string> . In case you cannot use C++, try implementing a vector - like container on your own in C. Commented May 12, 2014 at 12:07
  • @AnmolSinghJaggi Thank you but i should do it with malloc Commented May 12, 2014 at 12:10
  • scanf("%s", buff) is a buffer overrun bug. It should be something more like scanf("%*s", buffsize, buff). Commented May 12, 2014 at 12:16

3 Answers 3

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;
}   
Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

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.
   }

6 Comments

Can you comment what are doing at last 5 lines. If you do it I will accept your answer!
Do not cast what malloc returns. stackoverflow.com/questions/605845/…
@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.
@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.
@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!
|

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.