need some help with arrays

P

pillip

I am trying to use fopen and fget to input two files and then output them
into one file. Each input file has two columns and 20 rows, however since
the first column in each input file is same ( numbers 0...19), i want the
output file to have 3 columns and 20 rows. Right now i am using a one
dimensional array "array1[SIZE]" to input each file:, and the output file
has 2 columns and 42 rows.

#include <stdlib.h>
#include <stdio.h>

#define SIZE 20

main()
{
char array1[SIZE], array2[SIZE];
FILE *fp;


if ( (fp = fopen("1a.data", "r")) == NULL)
{
fprintf(stderr, "Error opening file.");
exit(1);
}

while ( !feof(fp) )
{
fgets(array1, SIZE, fp);
printf("%s",array1);
}
fclose(fp);

printf("\n\n");

if ( (fp = fopen("1b.data", "r")) == NULL)
{
fprintf(stderr, "Error opening file.");
exit(1);
}

while ( !feof(fp) )
{
fgets(array2, SIZE, fp);
printf("%s",array2);
}
fclose(fp);


return(0);
}
 
L

Leor Zolman

I am trying to use fopen and fget to input two files and then output them
into one file. Each input file has two columns and 20 rows, however since
the first column in each input file is same ( numbers 0...19), i want the
output file to have 3 columns and 20 rows. Right now i am using a one
dimensional array "array1[SIZE]" to input each file:, and the output file
has 2 columns and 42 rows.

There are several approaches to this that would work well enough. The most
general solution, which would work no matter how many rows the two files
have, would be to read one line's worth of data (not necessarily "a line"
as you're doing) from each file, create a line of output right away by
processing that input, and going back for more (if any). In that case you'd
just have three file streams going at the same time.

The other approach, if you really want to read one line at a time, is to
collect the data up in memory and combine it after all the data has been
read. But unless there's some /really/ good reason for this, such as you
have to read to the end of the data before being able to calculate
something that goes at the beginning of the output stream, I'd recommend
the first approach. It is certainly more memory-efficient, anyway.

Since you've said you have two columns ("items") on each line of input, you
may want to consider reading the data in using fscanf to put everything
immediately into some variables, and then creating your output lines with
fprintf. That would make it very easy to select what to write (i.e., skip
the first item from each line of the 2nd file). It would also give you
ready-made hooks for sanity-checking your input as you read it (the return
values from fscanf, and the ability to check the values of the variables
you've just read into).

HTH,
-leor



#include <stdlib.h>
#include <stdio.h>

#define SIZE 20

main()
{
char array1[SIZE], array2[SIZE];
FILE *fp;


if ( (fp = fopen("1a.data", "r")) == NULL)
{
fprintf(stderr, "Error opening file.");
exit(1);
}

while ( !feof(fp) )
{
fgets(array1, SIZE, fp);
printf("%s",array1);
}
fclose(fp);

printf("\n\n");

if ( (fp = fopen("1b.data", "r")) == NULL)
{
fprintf(stderr, "Error opening file.");
exit(1);
}

while ( !feof(fp) )
{
fgets(array2, SIZE, fp);
printf("%s",array2);
}
fclose(fp);


return(0);
}

Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
P

pillip

OK i have tried as you said and it "almost" works. Only problem is that the
ouput file keeps showing the last row of the two input files continously. I
think i am not looping it correctly, but couldnt find out the mistake. Here
is the code:

#include <stdlib.h>
#include <stdio.h>

#define rows 20

main ()

{
FILE *fp;
float value1, value2;
int degree;
int i;
char filename[20];

if ((fp = fopen("1a.data", "r")) == NULL)
{
fprintf (stderr, "Error opening file.\n");
exit (1);
}

for (i =0; i < rows; i ++)
{
fscanf (fp, "%d %g", &degree, &value1);
}

fclose(fp);

if ((fp = fopen("1b.data", "r")) == NULL)
{
fprintf (stderr, "Error opening file.\n");
exit (1);
}

for (i =0; i < rows; i ++)
{
fscanf (fp, "%d %g", &degree, &value2);
}

fclose(fp);

puts ("Enter filename:");
gets (filename);

if ((fp = fopen(filename, "w")) == NULL)
{
fprintf(stderr, "Error opening file %s.", filename);
exit (1);
}

for (i=0; i < rows; i++)
{
fprintf(fp, "\n %d %f %f", degree, value1, value2);
}
fclose(fp);

return (0);
}



Leor Zolman said:
I am trying to use fopen and fget to input two files and then output them
into one file. Each input file has two columns and 20 rows, however since
the first column in each input file is same ( numbers 0...19), i want the
output file to have 3 columns and 20 rows. Right now i am using a one
dimensional array "array1[SIZE]" to input each file:, and the output file
has 2 columns and 42 rows.

There are several approaches to this that would work well enough. The most
general solution, which would work no matter how many rows the two files
have, would be to read one line's worth of data (not necessarily "a line"
as you're doing) from each file, create a line of output right away by
processing that input, and going back for more (if any). In that case you'd
just have three file streams going at the same time.

The other approach, if you really want to read one line at a time, is to
collect the data up in memory and combine it after all the data has been
read. But unless there's some /really/ good reason for this, such as you
have to read to the end of the data before being able to calculate
something that goes at the beginning of the output stream, I'd recommend
the first approach. It is certainly more memory-efficient, anyway.

Since you've said you have two columns ("items") on each line of input, you
may want to consider reading the data in using fscanf to put everything
immediately into some variables, and then creating your output lines with
fprintf. That would make it very easy to select what to write (i.e., skip
the first item from each line of the 2nd file). It would also give you
ready-made hooks for sanity-checking your input as you read it (the return
values from fscanf, and the ability to check the values of the variables
you've just read into).

HTH,
-leor
/tools/stlfilt.html
 
L

Leor Zolman

OK i have tried as you said and it "almost" works. Only problem is that the
ouput file keeps showing the last row of the two input files continously. I
think i am not looping it correctly, but couldnt find out the mistake. Here
is the code:
[snip]

You're reading in 20 rows, each time overwriting the same temporary
variables. When it is done reading, all you have is the last row's worth of
data, which you then write out 20 times.

You may want to re-read what I wrote... if you want to take my first
(suggested) approach, you'll need /three/ FILE *'s going all at once, two
for reading and one for writing. Open all three files, and in /each/
iteration of the loop read two lines and write out one.
-leor


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
M

Mac

I am trying to use fopen and fget to input two files and then output them
into one file. Each input file has two columns and 20 rows, however since
the first column in each input file is same ( numbers 0...19), i want the
output file to have 3 columns and 20 rows. Right now i am using a one
dimensional array "array1[SIZE]" to input each file:, and the output file
has 2 columns and 42 rows.

#include <stdlib.h>
#include <stdio.h>

#define SIZE 20

main()

int main(void) /* This will be mandatory in C99 and is good practice now */
{
char array1[SIZE], array2[SIZE];
FILE *fp;


if ( (fp = fopen("1a.data", "r")) == NULL)
{
fprintf(stderr, "Error opening file.");
exit(1);

exit(EXIT_FAILURE); /* 1 is not portable */
}

while ( !feof(fp) )

You don't want this test. feof() won't return true until after you attempt
to read beyond the end of the file, at which point you will have printed
some kind of garbage with the printf() statement below.
{
fgets(array1, SIZE, fp);
printf("%s",array1);
}
fclose(fp);

printf("\n\n");

if ( (fp = fopen("1b.data", "r")) == NULL)
{
fprintf(stderr, "Error opening file.");
exit(1);

see above
}

while ( !feof(fp) )

see above
{
fgets(array2, SIZE, fp);
printf("%s",array2);
}
fclose(fp);


return(0);

nothing wrong with return(0), but since you have included stdlib.h, you
can also return EXIT_SUCCESS, if you want.

Sorry I didn't answer your question. I don't understand it completely, and
since you didn't provide 1a.data, and 1b.data, I can't run it on my
machine to see what you are talking about.

--Mac
 
M

Mac

OK i have tried as you said and it "almost" works. Only problem is that the
ouput file keeps showing the last row of the two input files continously. I
think i am not looping it correctly, but couldnt find out the mistake. Here
is the code:

#include <stdlib.h>
#include <stdio.h>

#define rows 20

it is customary, when #defining some constant, to use all caps, like this:
#define ROWS 20

int main(void)
{
FILE *fp;
float value1, value2;
int degree;
int i;
char filename[20];

if ((fp = fopen("1a.data", "r")) == NULL)
{
fprintf (stderr, "Error opening file.\n");
exit (1);
exit(EXIT_FAILURE);

}

for (i =0; i < rows; i ++)
{
fscanf (fp, "%d %g", &degree, &value1);

fscanf() returns a value. You shouldn't ignore it, since it can help you
figure out if something has gone wrong. Also, in this loop, you just
repeatedly clobber the last value by overwriting the data in degree and
value1.
}

fclose(fp);

if ((fp = fopen("1b.data", "r")) == NULL)
{
fprintf (stderr, "Error opening file.\n");
exit (1);
}

for (i =0; i < rows; i ++)
{
fscanf (fp, "%d %g", &degree, &value2);

This loop has the same problem as the loop above.
}

fclose(fp);

puts ("Enter filename:");
gets (filename);

Never use gets(). It is impossible to use it safely. Use fgets(filename,
20, stdin), or scanf("%19s", filename) instead.
if ((fp = fopen(filename, "w")) == NULL)
{
fprintf(stderr, "Error opening file %s.", filename);
exit (1);

see above
}

for (i=0; i < rows; i++)
{
fprintf(fp, "\n %d %f %f", degree, value1, value2);

It is fairly obvious that this loop will print the same value over and
over again. I think you want one loop, two input files, and one output
file. You could also just use stdout for output, until you get the thing
working the way you want.
}
fclose(fp);

return (0);
}



[snip]
HTH,
-leor
/tools/stlfilt.html


Don't top-post. It makes the conversation very difficult to follow.

--Mac
 
P

pillip

Thanks i got it working

Leor Zolman said:
OK i have tried as you said and it "almost" works. Only problem is that the
ouput file keeps showing the last row of the two input files continously. I
think i am not looping it correctly, but couldnt find out the mistake. Here
is the code:
[snip]

You're reading in 20 rows, each time overwriting the same temporary
variables. When it is done reading, all you have is the last row's worth of
data, which you then write out 20 times.

You may want to re-read what I wrote... if you want to take my first
(suggested) approach, you'll need /three/ FILE *'s going all at once, two
for reading and one for writing. Open all three files, and in /each/
iteration of the loop read two lines and write out one.
-leor


Leor Zolman
BD Software
(e-mail address removed)
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software's free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html
 
D

Dave Thompson

char filename[20];
puts ("Enter filename:");
gets (filename);

Never use gets(). It is impossible to use it safely. Use fgets(filename,
20, stdin), or scanf("%19s", filename) instead.
But in the former case, you must then (find and) strip the trailing
\n, unless you actually want (and your system allows!) filenames
containing a newline; and in the latter case you cannot have filenames
containing whitespace (not permitted on some systems anyway).

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,310
Messages
2,571,603
Members
48,419
Latest member
EstelaCout

Latest Threads

Top