Thread: array of strings confused me

  1. #1
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198

    array of strings confused me

    I wrote this function to get 10 strings from the user, each with a max of 80 characters. it's an array of pointers to strings. when the first for loop executes it seems to be working fine but then when the second executes to check to see if the strings were stored, it just outputs the last string 10 times. what the heck...

    Code:
    void getstrings(char * star[MAX])
    {
        int count;
        char * buf;
    
        for (count = 0; count < MAX; count++)
        {
          fgets(buf, LIM, stdin);
          *(buf + strlen(buf) - 1) = '\0';
          puts(buf);
          star[count] = buf;
          puts(star[count]);
        }
        for (count = 0; count < MAX; count++)
        {
          puts(star[count]);
        }
    }

  2. #2
    Registered User
    Join Date
    Jan 2003
    Posts
    648
    First of all, buf points no where. So when you send it to fgets, it will try to modify some random memory location --> bad. So you need to initialize it:
    Code:
    char buf[LIM];
    ... because after all, you're only getting LIM elements. And btw, fgets will automatically close off your string with a NULL so that line after the fgets is redundant and useless.

    The reason you are getting the same thing 10 times is because all the pointers in star[] point to the same thing: buf. What you need to do is allocate a new buffer everytime or start off with a fixed-length buffer.

    Method #1: Fixed-length buffer:
    Code:
    void getstrings(char star[MAX][LIM])
    {
        int count;
    
        for (count = 0; count < MAX; count++)
        {
          fgets(star[count], LIM, stdin);
        }
    
        for (count = 0; count < MAX; count++)
        {
          puts(star[count]);
        }
    }
    That require modifying your client code.

    Method #2: Allocating a new buffer everytime:
    Code:
    void getstrings(char * star[MAX])
    {
        int count;
        char buf[LIM];
    
        for (count = 0; count < MAX; count++)
        {
          fgets(buf, LIM, stdin);
          star[count] = (char *)malloc(LIM);
          strcpy(star[count], buf);
        }
    
        for (count = 0; count < MAX; count++)
        {
          puts(star[count]);
        }
    }
    
    
    // ... somewhere else in your code ...
    {
      getstrings(array);
      // do something with it
      
      // now free all the memory
      for (count = 0; count < MAX; count++)
      {
        free(star[count]);
      }
    }

  3. #3
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198
    hey thanks a lot, that helps. The reason I was putting that null character at the end is because fgets() automatically adds a newline character at the end and this overwrites it. that way i put my newlines where i want. i'm a beginner programmer and i have no idea what you mean when you say free the memory or what the free() function is.

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> it's an array of pointers to strings.
    which is why they all point to the same invalid array of bytes with this line of code:

    >> star[count] = buf;
    replace that with strcpy and it will work.

    >>char * buf;
    'buf' points to no memory, making it an entry point for access violations. Declare a local array of bytes within the function instead (using LIM as the size perhaps).
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198
    dangit i was in the middle of changing my code when i posted. i have

    Code:
    void getstrings(char * star[MAX])
    {
        int count;
        char buffer[LIM];
        char * buf;
    
        for (count = 0; count < MAX; count++)
        {
          buf = fgets(buffer, LIM, stdin);
          *(buf + strlen(buf) - 1) = '\0';                /* takes out the null character */
          star[count] = buf;
        }
        for (count = 0; count < MAX; count++)
        {
          puts(star[count]);
        }
    when i had a puts(star[count]); statement right after i assign buf to star[count] it displayed the correct value, indicating to me that the program successfully stored my string into that variable. but in the next for loop it begs to differ... it doesn't make sense to me
    and when i tried to use
    Code:
    void getstrings(char star[MAX][LIM])
    i had some trouble...

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    As stated, all you're doing is a pointer assignment. You're making each element in the array (a pointer) point to buf. You then change what buf points to, so all of them end up pointing to whatever it is buf points to. In the end, when the function ends, buf goes out of scope, so now all of your pointers point to where buf was, which is a non-valid place in memory.

    You need to malloc memory for each string, make each pointer in the array point to its own allocated block of memory, and at each time through the loop, copy the contents into the corresponding allocated block as has been stated in previous posts.

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

  7. #7
    Advanced Novice linucksrox's Avatar
    Join Date
    Apr 2004
    Location
    Michigan
    Posts
    198
    i don't know how to malloc, i'm that new to programming in C, so i guess i need to allocate the memory beforehand, using MAX and LIM and just use an array of char arrays instead of string pointers. geez all i'm trying to do is store 10 strings from input.
    and now i understand why my original code is wrong

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. intializing an array of strings
    By doubty in forum C Programming
    Replies: 4
    Last Post: 06-19-2009, 12:59 PM
  2. Replies: 1
    Last Post: 03-19-2009, 10:56 AM
  3. Swapping strings in an array of strings
    By dannyzimbabwe in forum C Programming
    Replies: 3
    Last Post: 03-03-2009, 12:28 PM
  4. printing an array of strings
    By linucksrox in forum C Programming
    Replies: 3
    Last Post: 05-11-2004, 03:31 PM
  5. Array of Strings
    By mjpars in forum C Programming
    Replies: 8
    Last Post: 08-21-2003, 11:15 PM