Given the fact that most of the answers given here are flawed in some way or another:
The accepted answer, for instance, states that a[i][10] accesses the tenth char in the row. This is completely false. As arrays are zero-indexed, this actually attempts to access the eleventh char in a row, which could well be out of bounds.
The same answer shows how a 2D array is divided up in rows and columns. This, too, is false. An array, be it 2D or 1D is a contiguous block in memory. Just one big row of chars. The actual layout of your array a[100][10], then looks like this. I've just noticed the answer mentions this, but still:
|/a[0][0] ===============================\\===============>a[99][9]\|
|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|
Just 100*10 chars in a row. Accessing a[1][0], then is the same as accessing a[0][10] or indeed a[10]. The out-of-bounds risk of using a[i][10] occurs if i is 99, because as you can see, the last char in the array is situated at a[99][9]. All memory beyond that point is off-limits.
The example given, in rows and column format where the input is a, b and c, then does not look like this:
_ _ _ _ _ _ _ _ _ a
_ _ _ _ _ _ _ _ _ b
_ _ _ _ _ _ _ _ _ c
But rather, it'll look like this:
0 1 2 3 4 5 6 7 8 9
_ _ _ _ _ _ _ _ _ _
a _ _ _ _ _ _ _ _ _
b _ _ _ _ _ _ _ _ _
c _ _ _ _ _ _ _ _ _
@TomFenech's answer is a lot better, using fgets here makes sense. However, to dot the i's and cross the T's: the nul-terminating char won't be read by fgets. The function will read at most n-1 chars, where n is the specified max length, as the documentation states:
The fgets function reads at most one less than the number of characters specified by n from the stream pointed to by stream into the array pointed to by s. No additional characters are read after a new-line character (which is retained) or after end-of-file.
However, fgets stops reading if, and only if it encounters a line-break or an EOF. It will not stop after encountering a NUL char. Keep that in mind, but in your case, it shouldn't be a worry.
When using fgets, however, you can find tons of snippets that call fflush(stdin); up front, to clean the input buffer. This invokes undefined behaviour, however, and you do well reading the buffer until it's empty first. Tom Fench left this out, so for completeness, I thought I'd mention it here, too. Other than that, I'd say his answer is accurate.
So, with this in mind, here's my suggestion:
Do away with your fixed-sized buffer. How many strings a will contain depends on user input. That means the array itself should be one of variable length. Thankfully, C (since C99) has just the thing you need: Variable Length Arrays - or VLA's for short would be preferable here. Here's what I wrote as a quick test/proof of concept:
#include <stdio.h>
#include <stdlib.h>
int main ( void )
{
int i, n;
puts("How many words do you wish to enter?");
scanf(" %d", &n);//get size of input array
while((i=getchar()) != EOF && i != '\n');//"flush" stdin
char a[n][10];
printf("Please enter %d words now\n", n);
for (i=0;i<n;++i)
fgets(a[i], 9, stdin);//get 9 char input, not 10 (10th char is nul terminator)
for (i=0;i<n;++i)
printf("Line %d: %s\n", i+1, a[i]);//print each input line
return 0;//return
}
You can compile this on a *NIX system using gcc:
$ gcc -std=c99 your_code.c -o progName
$ ./progName
And run it. It works as expected.
Mind you, the input buffer for each entry is only 10 chars long. That means that a word like: "successful" is a no-go (it's 10 chars long, but a string requires a NUL-terminating char, too). I'd choose to use a bigger buffer for the actual input if I were you.
Since we're using a VLA, we no longer use up 1000 bytes of stack space by default (a[100][10] uses that much). If the value of n is 10, we could make our buffer 100 chars big, and still end up using no more memory than you are doing now. So perhaps consider using:
char a[n][24];
for (i=0;i<n;++i)
fgets(a[i], 24, stdin);
Ideally, you'd clean the stdin buffer after each fgets call in the loop, too:
int j;//for clearing the buffer
for (i=0;i<n;++i)
{
fgets(a[i], 24, stdin);
if (strlen(a[i]) >= 23)//buffer overflow averted, clear stdin
while ((j = getchar()) != EOF && j != '\n');//clear buffer
}
If you don't, and you leave the buffer at 10, you could encounter something like this:
Please enter 2 words now
successful?
Line 1: successfu
Line 2: l?
The full code, now looks something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //add this
int main ( void )
{
int i, j, n;//extra temp var
puts("How many words do you wish to enter?");
scanf(" %d", &n);
while((j=getchar()) != EOF && j != '\n');
char a[n][10];
printf("Please enter %d words now\n", n);
for (i=0;i<n;++i)
{
fgets(a[i], 10, stdin);
if (strlen(a[i] >= 9)//<-- added
while ((j=getchar()) != EOF && j != '\n');//added
}
for (i=0;i<n;++i)
printf("Line %d: %s\n", i+1, a[i]);
return 0;//return
}
The program compiles and runs in exactly the same way, though.
If you want to accommodate larger buffers if the user only wants to pass, say, 2 words as input, you can use VLA's for that, too:
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //add this
//max buffer total 1000 chars is what you are using with a[100][10]
#define MAX_TOTAL_BUFFER 1000
//don't allow more than 80 chars per entry
#define MAX_SINGLE_BUFFER 80
//added for safety
#define MIN_SINGLE_BUFFER 10
int main ( void )
{
int i, j, n. buf_len;
puts("How many words do you wish to enter?");
scanf(" %d", &n);
buf_len = MAX_TOTAL_BUFFER/n; // int/int yields int 1000/3 == 333
if (buf_len > MAX_SINGLE_BUFFER)
buf_len = MAX_SINGLE_BUFFER;
else if (buf_len < MIN_SINGLE_BUFFER) //mind you, risk of stack overflow here
buf_len = MIN_SINGLE_BUFFER;
while((j=getchar()) != EOF && j != '\n');
char a[n][buf_len];
printf("Please enter %d words (max %d chars long)\n", n, buf_len-1);
for (i=0;i<n;++i)
{
fgets(a[i], buf_len, stdin);
if (strlen(a[i] >= buf_len)//<-- added
while ((j=getchar()) != EOF && j != '\n');//added
}
for (i=0;i<n;++i)
printf("Line %d: %s\n", i+1, a[i]);
return 0;//return
}
Play around with the max and minima for the buffers, and see how far you can push this until your stack eventually overflows. Also check the value of n after you get it from the user. If the user passes 0, this program doesn't deal with it properly. Either prompt the user again for a positive n, use a default value, or exit.
If n is negative, either use its absolute value (or multiply by -1), prompt again or exit... all of these things make for good exercises in interactive CLI C programs. Separating the logic, and writing functions will prove useful to turn this snippet into actual, useful code.
scanf("%s", a[i]);a[i][10]is out of bounds,char a[100][10];means that the highest index ofa[i]is 9. Given that yourscanfformat specifies a string, you want to pass&a[i]a[0][10], which is the same as writinga[1][0], then just start the loop withint i = 1and run it whilei <=n. Keep in mind, though that the first 10 bytes (a[0][0]througha[0][9]will never be used in that case, and are just a waste of stack space