Like Tree1Likes
  • 1 Post By quzah

Dynamically Allocated Array Troubles

This is a discussion on Dynamically Allocated Array Troubles within the C Programming forums, part of the General Programming Boards category; I have been assigned a project for my class which requires me to read in values from stdin then dynamically ...

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    4

    Dynamically Allocated Array Troubles

    I have been assigned a project for my class which requires me to read in values from stdin then dynamically allocate an array "a" based upon the number of characters. After that, I must print the array backwards.

    **NOTE**
    The input is being redirected from a .txt file.


    Code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
    
    char *a;         // Declare the array pointer
    int CharCount; //counts the # of characters in 
                        // input file
    int i;             // used to loop through stdin
    
    while (getchar()!=EOF) CharCount++;
    This is where my problem is, I simply do not understand the functions of attaining data from the input stream.

    For example: After I determine the amount of characters in the input stream, I would then proceed to dynamically allocate array "a" based upon CharCount.

    Code:
    a = malloc(CharCount * sizeof(a));
    
    if(!=a)
    {
    printf("Allocation failed. Exiting.\n");
    exit(EXIT_FAILURE);
    }
    At this point I have to save the characters from stdin to the array, I am stuck at re-retrieving the characters from the beginning of the input file.

    Example:

    Code:
    for (i=0;i<c;i++)
    a[i]=getchar();
    Just not sure how to make it read from the beginning of the input file.
    If I choose to print the array, I get random characters, which I interpret as a problem with getchar()'s position in the input stream. If I can solve that problem, I can easily print the characters in reverse order.

    Help would be greatly appreciated, I'm new to this stuff.

    P.S. I google'd "How to return getchar() to beginning of input stream" to no avail.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You have a couple of problems.

    1. You use 'CharCount' without initializing it, so it isn't going to start counting at zero.
    2. You aren't storing those characters anywhere, so you can't get them back again.

    The input stream is like a deck of face down cards. If you want to look at a card, you have to turn it over (take it off the deck and look at it). You can't put it back once you have removed it.

    Technically you can (ungetc), but you can only put back one card (the last card you looked at), and not any more of them. Then you can take more off, and then you can put the last one back, but you can't take two off, then put two back.

    That means you need to keep track of them some place. You can cheat and use the program stack. Or, you can dynamically keep reallocating the space you need, and adding on the new character.

    I'll let you think about both of those. Give it a shot.


    Quzah.
    nonpuz likes this.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    4
    Or, you can dynamically keep reallocating the space you need, and adding on the new character.

    Quzah.[/QUOTE]

    Maybe something like this:

    Code:
    int CharCount=0;
    char c;
    char *a;
    
    while ((c=getchar()) != EOF)
       {
    	   if (CharCount==0) {
    		   a=malloc((CharCount + 1) * sizeof(a));
    		   a[0]=c;
    	   }
    	   else {
    		   a=realloc((CharCount + 1) * sizeof(a));
    		   a[CharCount]=c;
    	   }
    	   CharCount++;
       }
    I'm not sure exactly how to use the realloc() function.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,704
    You should read up on realloc: your example does not even call it with sufficient arguments.

    Also, getchar() returns an int, so c should be an int, not a char.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Jun 2011
    Posts
    4
    Quote Originally Posted by laserlight View Post
    You should read up on realloc: your example does not even call it with sufficient arguments.

    Also, getchar() returns an int, so c should be an int, not a char.
    Code:
     
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
       char *a;
       int c;
       int CharCount=0;
       int i=0;
    
       c=getchar();
       a=malloc((CharCount+1) * sizeof(a)); // 1 added to prevent 0 bytes being allocated
       a[0]=c;
       CharCount++;
    
       if (!a) {
    	   printf("Allocation failed. Exiting.");
    	   exit(EXIT_FAILURE);
       }
    
       while ((c=getchar()) != EOF)
       {
    	   *a=realloc(NULL, CharCount * sizeof(a));
    	   a[CharCount]=c;
    	   CharCount++;
       }
    I'm getting closer, the first character is wrong, which maybe can be fixed by converting int to char (?), and getchar() is reading 3 extra characters after the final character from input. I know this can easily be fixed by deleting the extra 3 characters from the array before printing but I want it to function as efficiently as possible.

    You've both been a great help so far, thanks.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,704
    sizeof(a) returns the size of the pointer. You actually want sizeof(*a), but it is guaranteed that sizeof(char) == 1.

    Also, read carefully how to use realloc to "expand" your dynamic array.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
       a=malloc((CharCount+1) * sizeof(a)); // 1 added to prevent 0 bytes being allocated
    That's wrong. You are getting the size of a pointer, not the size of a character (which is always 1 anyway).
    Code:
       while ((c=getchar()) != EOF)
       {
    	   *a=realloc(NULL, CharCount * sizeof(a));
    The first argument is wrong, the assignment is wrong, and you shouldn't directly assign it anyway:
    Code:
    while( ... )
    {
        char *t = realloc( a, CharCount + 1 );
        if( t != NULL )
            a = t;
        else
            outofmemoryoops();
        a[ CharCount++ ] = c;
    }
    Now then, if you want it to be a string, you need to have allowed for a nul character at the end, and you need to keep assigning it to the newest spot allocated, after you overwrite the old one with the new character. There's all sorts of fun ways to do that:
    Code:
    char in[2] = { 0 };
    while( (in[0]=getchar()) != EOF )
    {
        ...
        strcat( a, in );
    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Jun 2011
    Posts
    4
    Thanks again for the help on this, I'm going to sleep on it and most likely post more questions tomorrow. If I get it running I'll post the final source up here.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamically Allocated Array
    By chris4 in forum C Programming
    Replies: 9
    Last Post: 05-06-2011, 10:01 AM
  2. Initializing a 2D array dynamically allocated
    By newboyc in forum C Programming
    Replies: 5
    Last Post: 02-01-2011, 12:08 PM
  3. Dynamically allocated array
    By dre in forum C Programming
    Replies: 17
    Last Post: 08-13-2009, 06:57 PM
  4. Dynamically Allocated Array
    By vb.bajpai in forum C Programming
    Replies: 3
    Last Post: 06-17-2007, 08:40 AM
  5. Run-time error with dynamically allocated 3-D array
    By OceanDesigner in forum C Programming
    Replies: 2
    Last Post: 10-21-2005, 02:29 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21