Solved

use C to create a runtime array of strings

Posted on 2003-11-02
12
411 Views
Last Modified: 2012-08-13
hi
I want to create an array of strings in C. I want to use a pointer to char pointer (char **).
The no. of strings will known at runtime only. The length of each strings is also known at runtime only. How can i go about it?

I tried the following


//Create a zagged array of strings based on user input
//USE C ONLY

#include<stdio.h>
#include<string.h>
int main()
{
int i=0,n,m;
char **str_array;
char *temp;
printf("\n Enter the number of strings : ");
scanf("%d",&n);

if(!(str_array =  (char**)malloc(n*sizeof(char*))))
        {
        printf("incorrect memory allocation");
        return;
        }

while(i<n)
        {
        temp="\0";
        scanf("%s",&temp);
        str_array[i]=(char*)malloc((strlen(temp))*sizeof(char));  //str_array[i] = "string i" works
        strcpy(str_array[i++],temp);
        str_array[i++]="hello";
        printf("\t%d\n",scanf("%s",&str_array[i++]));i
        }

for(i=0;i<n;i++)
        printf("%s\n",str_array[i]);
for(i=0;i<n;i++)
      free(str_array[i]);
free(str_array);


but somewhere segmentation fault occurs.

Within the while loop if i use
str_array[i] = "some stirng"

i.e., hard coding the strings, it works. But it doesn;t work for user input. I think i am not able to pass the addresses correctly. Can some one help me do it. A little explanaation will be greatly appreciated.


please do not give me examples with integer pointers. I know the solution for them. I am having trouble in understanding how the char* pointer to array works.
Thanks
K
0
Comment
Question by:bsarvanikumar
12 Comments
 
LVL 19

Expert Comment

by:Dexstar
Comment Utility
bsarvanikumar:

> How can i go about it?

You're doing a couple of things wrong, but they are all minor.

Change this:
> char *temp;

To this:

     char temp[1024];

Otherwise you won't allocate enough memory to hold the user's input.

>         strcpy(str_array[i++],temp);

For this part, do not use i++ ... Just use i, and then put one i++ at the end.  You need to only work with one string at a time.

>         str_array[i++]="hello";
>         printf("\t%d\n",scanf("%s",&str_array[i++]));i

Do you even need this part?  I don't think you do.

> Within the while loop if i use
> str_array[i] = "some stirng"
>
> i.e., hard coding the strings, it works. But it doesn;t work for user input.
> I think i am not able to pass the addresses correctly. Can some one help me
> do it. A little explanaation will be greatly appreciated.

I think it is mostly the i++ issues.  If you use i++, it increments the value of i, so now you're dealing with the next item in the array, and you haven't allocated any memory for it yet.

Hope that helps,
Dex*
0
 
LVL 19

Expert Comment

by:Dexstar
Comment Utility
bsarvanikumar:

> A little explanaation will be greatly appreciated.

This site offers a very good explanation that will help you:
http://www-ee.eng.hawaii.edu/Courses/EE150/Book/chap7/subsection2.1.1.2.html

Dex*
0
 

Author Comment

by:bsarvanikumar
Comment Utility
hi

I made a couple of mistakes in my question. Here is an updated one. Thanks to Dex* for pointed them out. Guess i was trying out different option and forgot to remove the debugging stuff.


I want to create an array of strings in C. I want to use a pointer to char pointer (char **).
The no. of strings will known at runtime only. The length of each strings is also known at runtime only. How can i go about it?

I tried the following


//Create a zagged array of strings based on user input
//USE C ONLY

#include<stdio.h>
#include<string.h>
int main()
{
int i=0,n,m;
char **str_array;
char *temp;
printf("\n Enter the number of strings : ");
scanf("%d",&n);

if(!(str_array =  (char**)malloc(n*sizeof(char*))))
        {
        printf("incorrect memory allocation");
        return;
        }

while(i<n)
        {
        temp="\0";
        scanf("%s",temp);
        str_array[i]=(char*)malloc((strlen(temp))*sizeof(char));  //str_array[i] = "string i" works
        strcpy(str_array[i++],temp);
        printf("\t%d\n",scanf("%s",str_array[i]));i
        }

for(i=0;i<n;i++)
        printf("%s\n",str_array[i]);
for(i=0;i<n;i++)
      free(str_array[i]);
free(str_array);


but somewhere segmentation fault occurs.

Within the while loop if i use
str_array[i] = "some stirng"

i.e., hard coding the strings, it works. But it doesn;t work for user input. I think i am not able to pass the addresses correctly. Can some one help me do it. A little explanaation will be greatly appreciated.


please do not give me examples with integer pointers. I know the solution for them. I am having trouble in understanding how the char* pointer to array works.
Thanks
K
0
 
LVL 4

Expert Comment

by:brunomsilva
Comment Utility
Hi,

i think you should use a linked list for it.

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

typedef struct _ll_ {
      char *text;
      struct _ll_ *next;
    } *stringList, sL;

stringList addString(char *str, stringList sl)
{
    stringList temp, i = sl;
    temp = (stringList) malloc(sizeof(sL));
    temp->text = strdup(str);
    temp->next = NULL;
    if (sl) {
          while (i->next)
              i = i->next;
          i->next = temp;
      return (sl);
    } else
      return (temp);
}

char *elementAt(int pos, stringList sl)
{
    int i = 0;
    stringList temp = sl;
    while (temp && i < pos) {
          temp = temp->next;
        i++;
    }
    if (temp)
      return (temp->text);
    else
      return (NULL);
}

// Example

int main()
{
    stringList l = NULL;

    l = addString("s0", l);
    l = addString("s1", l);
    printf("%s", elementAt(0, l));      // this should print s0
    printf("%s", elementAt(1, l));      // this should print s1
}

i think this will suit your needs.

Cheers,
  Bruno
0
 
LVL 19

Expert Comment

by:Dexstar
Comment Utility
bsarvanikumar:

> Thanks to Dex* for pointed them out.
First of all, you didn't make the change for "char *temp;".  So start with that.

Secondly, change this:
        strcpy(str_array[i++],temp);
        printf("\t%d\n",scanf("%s",str_array[i]));i

To this:
        strcpy(str_array[i],temp);
        printf("\t%d\n",scanf("%s",str_array[i]));
        i++;

Also, I don't know why you need that 2nd scanf.  If you scanf into temp, and then copy temp into your string, what do you need the 2nd scanf for?

Also, change this:
        str_array[i]=(char*)malloc((strlen(temp))*sizeof(char));

To this:
        str_array[i]=(char*)malloc((strlen(temp)+1)*sizeof(char));

You need to +1 to allocate space for the NULL at the end.


Dex*
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 4

Expert Comment

by:oumer
Comment Utility
     int i=0,n,m;
      char **str_array;
      char temp[MAX_LEN]; //define max_len to something big
      printf("\n Enter the number of strings : ");
      scanf("%d",&n);
      
      if(!(str_array =  (char**)malloc(n*sizeof(char*))))
      {
            printf("incorrect memory allocation");
            return;
      }

      fflush(stdin);
               //this will make the first gets in the next loop work, otherwise the first
              //gets will get the newline of the first input. I use gets because if you use
              //scanf, whitespace will also be considered as an input separator so putting "hello there" will be taken into two strings instead of one

      while(i<n)
      {
            gets(temp);
            str_array[i]=(char*)malloc((strlen(temp))*sizeof(char));  
            strcpy(str_array[i++],temp);
      }
0
 

Author Comment

by:bsarvanikumar
Comment Utility
changes I made

in the declaration part

char *temp;
to
char temp1[1024];
char *temp=temp1;

in the while loop

while(i<n)
        {
        temp="\0";
        scanf("%s",temp);
        str_array[i]=(char*)malloc((strlen(temp))*sizeof(char));  //str_array[i] = "string i" works
        strcpy(str_array[i++],temp);
        printf("\t%d\n",scanf("%s",str_array[i]));i
        }

to

while(i<n)
        {
        temp="\0";
       
        printf("\n %d",scanf("%s",temp)); //this doesn;t get printed
        printf("\n %d\t", strlen(temp));  //this doesn't get printerd
        str_array[i]=(char*)malloc((strlen(temp)+1)*sizeof(char));
        strcpy(str_array[i++],temp);
        }


it still gives a seg fault at  
printf("\n %d",scanf("%s",temp));


Please bear with me while I used temp pointer to temp1. I want to understand pointers and hence am tryint to use them a lot.

Thanks
K
0
 
LVL 3

Expert Comment

by:guynumber5764
Comment Utility
>>> str_array[i] = "some stirng"

When you assign a string you are doing two things:
- allocating a block of memory (11 bytes in this case)
- setting str_array[i] to point to that block.

scanf() (or gets()) does not allocate memory...it must be given a place to put the input.  hence:
char temp[1024]

The following code fragment is probably what you are looking for

char linebuf[1024];
:
gets(linebuf);
str_arry[i] = strdup(linebuf);
:

first allocate a buffer.  We only need to do this once because we will reuse it forever.
Load a line of input into the buffer.
Allocate a memory block exactly the right size for the line we just read and copy the string into it.

E.
0
 

Author Comment

by:bsarvanikumar
Comment Utility
Finally my own solution

#include<stdio.h>
#include<string.h>
int main()
{
int i=0,n,m;
char **str_array;
char temp1[1024];
char *temp=temp1;

printf("\n Enter the number of strings : ");
scanf("%d",&n);

//alloc memory for no of strings / char pointers
if(!(str_array =  (char**)malloc(n*sizeof(char*))))
        {
        printf("incorrect memory allocation");
        return;
        }

//read the strings
while(i<n)
        {
        scanf("%s",temp);
        //allocate memory for each string
        str_array[i]=(char*)malloc((strlen(temp)+1)*sizeof(char));
        strcpy(str_array[i++],temp);
        }

//print array
for(i=0;i<n;i++)
        printf("string %d = %s\n",i+1,str_array[i]);

//free memory
//for each string
for(i=0;i<n;i++)
        free(str_array[i]);
//for string array
free(str_array);
return;
}
0
 

Accepted Solution

by:
ee_ai_construct earned 0 total points
Comment Utility
PAQed, with points refunded (500)

ee_ai_construct - (re-order part number #xm34)
Community Support Moderator
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

A short article about problems I had with the new location API and permissions in Marshmallow
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now