Your main loop in scanArea()
has problems. It is currently:
while ((c=fgetc(in)) != EOF)
{
if ((c=fgetc(in)) == 10)
{
c++;
m++;
n = 0;
}
p[m][n] = (c=fgetc(in));
n++;
}
The loop condition reads a character. The if statement immediately reads the next character, jettisoning the first. You then read yet another character to assign to the array, jettisoning the second too. This means you skip two-thirds of the characters. You also increment c
when it's a newline, which is odd and pointless. Newline should be written '\n'
and not as 10.
You need something that's less enthusiastic about reading characters:
while ((c = fgetc(in)) != EOF)
{
if (c == '\n')
{
m++;
n = 0;
}
else
p[m][n++] = c;
}
This is still a bit dangerous; it will store any number of any sort of character except newline into the array, without concerns about the bounds on the array, either on a single line or number of lines in total. But it doesn't skip two-thirds of the data.
On further review, I observe that m
, n
and c
are shown as global variables; they should be local to scanArea()
. You should avoid global variables whenever possible. When necessary, they should be made static
in a file unless they really must be shared between source files. Then you need to follow the guidelines in How do I use extern
to share variables between source files to make sure everything is consistent.
There is only one scanArea()
and m
, n
and c
are only used there.
Then there is no excuse for them not being local. Indeed, if you called scanArea()
twice, the fact that these variables are global would mean that on the second invocation, the indexing would start at an array location that is way out of bounds and get worse from there onwards.
Working code
I make functions static
until there's a proven need for them to be visible in another source file. Not everyone is as anal retentive about this as I am.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void printArea(int len, char p[len][len])
{
FILE *out = fopen("spielfeld.txt", "w");
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
putc(p[i][j], out);
putc('\n', out);
}
fclose(out);
}
static int scanArea(int len, char p[len][len])
{
FILE *in = fopen("spielfeld.txt", "r");
if (in == 0)
return 1;
else
{
int m = 0;
int n = 0;
int c;
while ((c = getc(in)) != EOF)
{
if (c == '\n')
{
m++;
n = 0;
}
else if (n >= len || m >= len)
{
fprintf(stderr, "Accessing array out of bounds at p[%d][%d]\n", m, n);
exit(1);
}
else
p[m][n++] = c;
}
}
fclose(in);
return 0;
}
static void showArea(int len, char p[len][len])
{
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
putchar(p[i][j]);
putchar('\n');
}
}
int main(void)
{
int len = 12;
char arr[len][len];
memset(arr, '1', len * len);
puts("Before:");
showArea(len, arr);
printArea(len, arr);
scanArea(len, arr);
puts("After:");
showArea(len, arr);
}
When run on Mac OS X 10.10.1 (compiled with GCC 4.8.1), I get the output:
Before:
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
After:
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
111111111111
All works, except my 8th line is completly blank, so now I got 13 lines instead of 12.
I can't account for your blank 8th line.
I note that the file name is repeated; repetition of things like file names leads to bugs. Ideally, the code should be revised so that the reading and writing functions are passed the name of the file to use, and the calling code should supply that name. However, that is a little beyond the scope of the immediate problem.
Also note that if showArea()
was modified to take a file stream argument (void showArea(FILE *fp, int len, char p[len][len])
and the I/O calls were revised appropriately, then the code in printArea()
could be revised to open the file, call showArea()
, and then close the file.