Question

The goal of my assignment (ONLY C, NO C#,CPP ect...) was to get strings from the user, then trim the matrix to fit the exact data. This is my code:

    void main(){
    char** text=Q1();
    int i;
    printf("Lines entered:\n");
    for(i=0;i<sizeof(text)/sizeof(char*);i++)
        printf("%s\n",text[i]);
}

char** Q1(){
    char OOM[]="Out of memory! exiting.";
    char **buf=(char**)calloc(BUFFER,sizeof(char*)),**text;
    int i,j;
    if(buf==NULL){
        printf(OOM);
        exit(0);
    }
    for(i=0;i<BUFFER;i++){
        buf[i]=(char*)calloc(BUFFER,sizeof(char));
        if(buf[i]==NULL){
            printf(OOM);
            exit(0);
        }
    }
    i=0;
    do{
        i++;
        printf("Enter string #%d:\n",i);
        gets(buf[i-1]);
    }while(strlen(buf[i-1])>0 && i-1<BUFFER);
    text=(char**)calloc(i,sizeof(char*));
    if(text==NULL){
        printf(OOM);
        exit(0);
    }
    for(j=0;j<i;j++){
        text[j]=(char*)calloc(strlen(buf[j]),sizeof(char));
        if(text[j]==NULL){
            printf(OOM);
            exit(0);
        }
        strcpy(text[j],buf[j]);
    }
    free(buf);
    return text;
}

Now I know this could be done with realloc (which I am not quite familiar with just yet). I want to test that my allocations are okay and print the strings I saved in text. What is the most intuitive way of doing that? Thanks in advance!

Was it helpful?

Solution

First, this code:

for(i=0;i<sizeof(text)/sizeof(char*);i++)
  printf("%s\n",text[i]);

Will not work. sizeof(text) will return the size of a pointer since text is a char**. You'd want something like:

for (int i=0; i<BUFFER && text[i]!=0; i++)
  printf("%s\n",text[i]);

But this requires that the last entry in text is a null pointer so you would need to allocate 1 more entry than required and set it to NULL.

Otherwise, you'll need to find some other way to return the size.

Next:

i=0;
do{
  i++;
  printf("Enter string #%d:\n",i);
  gets(buf[i-1]);
}while(strlen(buf[i-1])>0 && i-1<BUFFER);

i will be 1 more than the number of entries. For example, if the user presses ENTER on the first try, i will be set to 1.

Why not?

for (i=0; i<BUFFER; i++) {
  printf("Enter string #%d:\n",i+1);
  gets(buf[i]);
  if (strlen(buf[i])­==0) {
    break;
  }
}

This way i is set to the number of entries.

Assuming you make the change above then:

text=(char**)calloc(i,sizeof(char*));

Will need to be changed to:

text=(char**)calloc(i+1,sizeof(char*));  // Include an extra entry for the sentinel
text[i] = 0;  // Add sentinel to indicate last entry

Also, when you allocate the space for the strings, you need to add 1 to the size to leave room for the terminating null character. So

text[j]=(char*)calloc(strlen(buf[j]),sizeof(char));

becomes

text[j]=(char*)calloc(strlen(buf[j])+1,sizeof(char));

And you forgot to free buf[0] to buf[BUFFER-1]

For the real question. I'm not sure what's expected your approach looks OK to me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top