Thread: a few questions on array of ptrs

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    141

    a few questions on array of ptrs

    Hi,

    I'll be obliged if someone answers my following queries regarding array of pointers:

    1. Say I've a some character delimited file and I want to read each string into each element of an array of ptr. How do I dynamically change the size of the array?

    2. Say the array of ptr is names: char *names [MAX]; Now say, names[1] contains "Angkar\0". How do I access each element of names[1]? I mean 'A', 'n' ...

    3. Say I dynamically read the contents of a file (delimited by \n) into an array of pointers. How do I know the number of elements in it (i mean the # of strings read)? One thing I can think of doing is count the # of times I read \n. But are there any better methods for it?

    Thanks,
    AK

  2. #2
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555
    1. malloc(), realloc() and free()
    2. (names[1])[charindex]
    3. Best way would be to have some int that keeps track of the total amount of entries. Another way would be to let the last element of the array be NULL. That way you won't know the size of the array without traversing through it though and is probably most useful for linked lists.

  3. #3
    Rabble Rouser Slacker's Avatar
    Join Date
    Dec 2005
    Posts
    116
    >How do I dynamically change the size of the array?
    You can't change the size of an array, it's a compile-time constant. You can simulate an array using malloc, calloc, or realloc, and free.

    >How do I access each element of names[1]?
    In this case, the same way you would a two dimensional array:
    Code:
    for ( i = 0; names[i] != '\0'; i++ )
      putchar ( names[1][i] );
    >How do I know the number of elements in it (i mean the # of strings read)?
    You have to have some kind of counter to make sure that while reading you don't overflow the array. Just use that counter, because when you finish readin the file, it should have the same value as the number of lines you read.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If you've stored the \0 properly, then
    printf( "%s", names[1] );
    will do the whole string for you, no loop required.

  5. #5
    Registered User
    Join Date
    Dec 2005
    Posts
    141
    Thanks to you all.

    Now as you instructed I'm trying to read a # delimited file into an array of pointers as:

    Code:
    FILE *f;
    	  int i=0;
    	  int j=0;
    	  char ch;
    	  char *data[6];
    	  clrscr();
    	  f=fopen("test.txt","r");
    	  ch = fgetc(f);
    	  printf("%c\n",ch);
    	  if ( feof(f) || ferror(f) ) {
    	   printf("Error opening file");
    	  }
    	  else {
    
    		  while (!(feof(f))){
    			for (i=0;i<6;i++){
    			 printf("Hi\n");
    			 do{
    			  ch=fgetc(f) ;
    			  (data[i])[j++] = ch;
    			 }while(ch!='#');
    
    			 (data[i])[j]='\0';
    			}
    		      }
    	  }
    	  fclose(f);
    My file looks like (since i know there are 3 entries I've fixed array size to 6 - first I want to learn to getdata rather than playing with the size):

    #S1
    AAJHKSHA--AHSA
    #S2
    AIWJOHWHDHSA
    #S3
    AILKJDHKLHLKJ--

    Unfortunately the o/p its throwing is:
    #
    Hi
    Hi
    Hi
    Hi
    and then going into an infinite loop.

    Could anyone shed some light upon the reason?
    Also, does this depend upon the i/p format? I mean shouldn't I expect (data[0])=S1 AAJHKSHA--AHSA ?

    Thanks,
    AK

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You don't have anything allocated for 'data'. All you have is an array of pointers, which don't point to anything.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Dec 2005
    Posts
    141
    Can you please show an example how to allocate something for data?

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Do you intentionally try to write bad code?
    Code:
    f=fopen("test.txt","r");
    	  ch = fgetc(f);
    	  printf("%c\n",ch);
    	  if ( feof(f) || ferror(f) ) {
    Here, instead of simply testing f to see if it's NULL, you decide to try and read from it, so that, if it's failed, you'll get an error. Does this seem "not smart" to you at all? Why don't you just check the return value of fopen. Now see how nice this is?
    Code:
    f = fopen( "foo", "r" );
    if( f == NULL )
    {
        ...file failed to open...
    }
    Or if you prefer it all done in a nice single line of code:
    Code:
    if( (f = fopen( "foo", "r" )) == NULL )
    {
        ...file failed to open...
    }
    As for allocating memory, there are tons of examples of this. Search the forum, or virtually any book on C. Here is a limited example in the FAQ.


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Registered User
    Join Date
    Dec 2005
    Posts
    141
    I'm sorry quzah but I'm new to this domain and trying to learn things under the guidance of expericed programmers like you.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    There are a few good things to keep in mind as you go:

    Functions that return something do so for a reason. It's good to be familiar with what they return and why they return it.

    There are lots and lots of functions in the standard library to to many tasks. It's good to learn as many of them as you can wrap your head around. Those you don't fully understand, it's good to have a reference for.

    I'd really suggest buying at least one good reference book, and finding as many good bookmarks for reference as you can.


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #11
    Registered User
    Join Date
    Dec 2005
    Posts
    141
    I'm using a book by Herbert Schildt (Turbo C/C++). But it has lots of info instead of analysis.
    And about the malloc I read that it returns a pointer to the 1st byte of the allocated space. Is this a good practice to allocate like this?
    Code:
      if ((data[i] = malloc(sizeof(char) * 100)) == NULL) {
        printf("Error : Null pointer returned)
      }
    and loop i 6 times?
    I do this since I fee that the left hand side must also contain a pointer and a * and a [] are both pointers. am i thinking right?

    AK

  12. #12
    Registered User
    Join Date
    Dec 2005
    Posts
    141
    Trying hard to find why even after allocating data my program gives o/p as:

    #
    Hi
    Hi
    Hi
    Hi
    and then infinite loop...

    Code:
    FILE *f;
    	  int i=0;
    	  int j=0;
    	  char ch;
    	  char *data[6];
    	  for(i=0;i<6;i++){
    	   if ((data[i] = (char *) malloc(sizeof(char) * 600)) == NULL)
    	      printf("Error: Null pointer returned\n");
    	  }
    	  clrscr();
    	  if((f=fopen("test.mul","r"))==NULL)
    	  {
    	  printf("Error\n");
    	  }
    	  ch = fgetc(f);
    	  printf("%c\n",ch);
    	   while (!(feof(f))){
    		for (i=0;i<6;i++){
    		     printf("Hi\n");
    			 do{
    			   ch=fgetc(f) ;
    			   (data[i])[j++] = ch;
    			 } while(ch!='#');
    
    			 (data[i])[j]='\0';
    		   }
    		   printf("%s",data[0]);
    	       }
    	  fclose(f);
    	  for(i=0;i<6;i++)
    	  free(data[i]);
    but a good point is that when i use a simple while !EOF with fgetc, the entire file is being printed as it is.



    AK

  13. #13
    old man
    Join Date
    Dec 2005
    Posts
    90
    You should write lots of little testbed programs so you can concentrate on the details of each thing.

    For example:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define STR_MAX 256
    #define STR_CNT 6
    
    int
    main (void)
    {
      char *buf, *data[STR_CNT];
    
      /* don't take malloc for granted -- test it */
      if ((buf = malloc (STR_MAX * STR_CNT)) == NULL)
      {
        fprintf (stderr, "malloc error");
        exit (EXIT_FAILURE);
      }
    
      /* don't trash the alloc'd address, either */
      char *tmp = buf; int i;
    
      for (i = 0; i < STR_CNT; i++)
      {
        data[i] = tmp;
        tmp += STR_MAX;
        sprintf (data[i], "data-%d", i);
      }
      /* did it work? */
      printf ("\n%s %s %s\n", data[0], data[1], data[2]);
      printf ("%s %s %s\n\n", data[3], data[4], data[5]);
    
      free (buf);
      return (EXIT_SUCCESS);
    }
    This represents just one way to allocate space for an array of strings.

    The point is, every program, no matter how complicated, is made up of fairly small, manageable steps -- so master those first.
    Last edited by eerok; 01-08-2006 at 09:10 PM.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > I'm using a book by Herbert Schildt (Turbo C/C++)
    Well that explains a lot - your book is broken.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A very long list of questions... maybe to long...
    By Ravens'sWrath in forum C Programming
    Replies: 16
    Last Post: 05-16-2007, 05:36 AM
  2. Class Template Trouble
    By pliang in forum C++ Programming
    Replies: 4
    Last Post: 04-21-2005, 04:15 AM
  3. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM
  4. Array Program
    By emmx in forum C Programming
    Replies: 3
    Last Post: 08-31-2003, 12:44 AM
  5. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM