user48870: Sorry if i'm asking too many silly questions but i'm really stumped on this one. I understand if I set a variable inside a loop that that variable won't be within scope from the outside of the loop. 
Usually I find that variables declared outside of a loop will be accessible inside the loop, modifiable within the loop, and hold their value when exiting the loop but in this case that doesn't seem to be happening.
There are books on the sd card.
I'm saving the name of each book to an array from within a while loop.
When the while loop is exited the array is still null.
How can I solve this? thanks
int amtBooks = 5; //this gets set previously but im not going to show all the code

// create an array the size of the amount of books
  char* book[amtBooks] = { NULL };

// assign the name of each book to the array
  int bookNum = 0;
  while (true) {

    File entry =  root.openNextFile();
      if (! entry) {
        break; // no more files
      }

    book[bookNum] = entry.name(); 

    Serial.println(book[bookNum]); // <--------PRINTS FINE HERE

    bookNum ++;

  }

  root.close(); // close the stream


Serial.println(book[0]); <---ONCE OUT OF THE WHILE LOOP NOTHING DISPLAYS?
Serial.println(book[1]);


user7508: 
variables declared outside of a loop will be accessible inside the
  loop, modifiable within the loop, and hold their value when exiting
  the loop

This is correct.

in this case that doesn't seem to be happening.

It is happening. The reason it looks like it doesn't is that
book[bookNum] is a pointer: the address of some data in memory. You
can check that the pointer does hold its value by printing it:
Serial.println((uintptr_t) book[bookNum]);

However, the statement you used:
Serial.println(book[bookNum]);

has a different meaning. It doesn't print the value of the variable
(i.e. the pointer): it prints the characters that are stored at the
pointed-to address, up to and excluding the first NUL.
Your problem comes from the fact that when you declare
File entry =  root.openNextFile();

you have a variable that is local to the loop. Then, when calling the
method
entry.name()

you get a pointer to an array of characters that belongs to the entry
object. This pointer is only valid as long as the object is in scope. As
soon as it gets out of scope (at the end of each loop iteration), the
entry object is destroyed and all memory belonging to it is released.
At this point the pointer you saved is a “dangling” pointer: it points
to an area of memory that has already been deallocated.
The proper fix is to allocate yourself the memory you need to hold the
character arrays, as in:
for (int bookNum = 0; bookNum < amtBooks; bookNum++) {
    File entry = root.openNextFile();
    if (!entry) break;
    const char *name = entry.name();
    book[bookNum] = (char *) malloc(strlen(name) + 1);
    strcpy(book[bookNum], name);
    Serial.println(book[bookNum]);
}

If you know in advance the maximum length of a book name, you could
follow the advice of Jot and Juraj and statically allocate the maximum
space you may need. That would be safer in terms of memory management.

48870: <p>Sorry if i'm asking too many silly questions but i'm really stumped on this one. I understand if I set a variable inside a loop that that variable won't be within scope from the outside of the loop. </p>

<p>Usually I find that variables declared outside of a loop will be accessible inside the loop, modifiable within the loop, and hold their value when exiting the loop but in this case that doesn't seem to be happening.</p>

<p>There are books on the sd card.
I'm saving the name of each book to an array from within a while loop.
When the while loop is exited the array is still null.</p>

<p>How can I solve this? thanks</p>

<pre><code>int amtBooks = 5; //this gets set previously but im not going to show all the code

// create an array the size of the amount of books
  char* book[amtBooks] = { NULL };

// assign the name of each book to the array
  int bookNum = 0;
  while (true) {

    File entry =  root.openNextFile();
      if (! entry) {
        break; // no more files
      }

    book[bookNum] = entry.name(); 

    Serial.println(book[bookNum]); // &lt;--------PRINTS FINE HERE

    bookNum ++;

  }

  root.close(); // close the stream


Serial.println(book[0]); &lt;---ONCE OUT OF THE WHILE LOOP NOTHING DISPLAYS?
Serial.println(book[1]);
</code></pre>
 7508: <blockquote>
  <p>variables declared outside of a loop will be accessible inside the
  loop, modifiable within the loop, and hold their value when exiting
  the loop</p>
</blockquote>

<p>This is correct.</p>

<blockquote>
  <p>in this case that doesn't seem to be happening.</p>
</blockquote>

<p>It is happening. The reason it looks like it doesn't is that
<code>book[bookNum]</code> is a pointer: the address of some data in memory. You
can check that the pointer <em>does</em> hold its value by printing it:</p>



<pre class="lang-c++ prettyprint-override"><code>Serial.println((uintptr_t) book[bookNum]);
</code></pre>

<p>However, the statement you used:</p>

<pre class="lang-c++ prettyprint-override"><code>Serial.println(book[bookNum]);
</code></pre>

<p>has a different meaning. It doesn't print the value of the variable
(i.e. the pointer): it prints the characters that are stored at the
pointed-to address, up to and excluding the first NUL.</p>

<p>Your problem comes from the fact that when you declare</p>

<pre class="lang-c++ prettyprint-override"><code>File entry =  root.openNextFile();
</code></pre>

<p>you have a variable that is local to the loop. Then, when calling the
method</p>

<pre class="lang-c++ prettyprint-override"><code>entry.name()
</code></pre>

<p>you get a pointer to an array of characters that belongs to the <code>entry</code>
object. This pointer is only valid as long as the object is in scope. As
soon as it gets out of scope (at the end of each loop iteration), the
<code>entry</code> object is destroyed and all memory belonging to it is released.
At this point the pointer you saved is a “dangling” pointer: it points
to an area of memory that has already been deallocated.</p>

<p>The proper fix is to allocate yourself the memory you need to hold the
character arrays, as in:</p>

<pre class="lang-c++ prettyprint-override"><code>for (int bookNum = 0; bookNum &lt; amtBooks; bookNum++) {
    File entry = root.openNextFile();
    if (!entry) break;
    const char *name = entry.name();
    book[bookNum] = (char *) malloc(strlen(name) + 1);
    strcpy(book[bookNum], name);
    Serial.println(book[bookNum]);
}
</code></pre>

<p>If you know in advance the maximum length of a book name, you could
follow the advice of Jot and Juraj and statically allocate the maximum
space you may need. That would be safer in terms of memory management.</p>
