ページ 1 / 1
ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月09日(水) 00:31
by シオリ
はじめまして
プログラム初心者でわからないことがあり,投稿させていただきました.
現在,数値が1列に約1000個並んだファイルがあり,それを読み込んだのち,
行数を固定した配列(例えば行は220個,列は定めずにファイルの読み込みが終了するまで)に格納したいと考えています.
1行n列のものを220行m列にするといったイメージです.
そして220行m列となった状態で,別のファイルに書き出したいと考えています.
現段階でここまで書いていますが,出力されずに悩んでいます.
iやj,mやn等,自分で設定しておきながらあまりわかっていません.
このような者ですがなにか助言していただけませんか?
よろしくお願いします.
コード:
#include <stdio.h>
int main (void)
{
int m,n,i,j;
double height[220][500];
FILE *text1,*text2;
text1=fopen("imput.txt","r");
printf("読み込みファイルオープン成功\n");
if(text1==NULL)
{
printf("ファイルがありません\n");
return -1;
}
text2=fopen("output.txt","w");
printf("書き出しファイルオープン成功\n");
if(text2==NULL)
{
printf("ファイルがありません\n");
return -1;
}
(fscanf(text1,"%lf",&height[220][500])!=EOF);
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
fprintf(text2,"%8.2f\n",height[i][j]);
}
}
fclose(text2);
fclose(text1);
return 0;
}
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月09日(水) 04:11
by かずま
適当に書いてみましたが、未完成で、ちょっと問題があります。
220 や 5 というのは、#define を使って書き換えるべきでしょう。
また、goto を使ってしまいましたが、これの是非を考えるべきでしょう。
テストが不十分です。データの個数が次の場合どうなるか、報告してください。
個数: 0, 1, 219, 220, 221, 1000, 1099, 1100, 1101
そうして、あなたのプログラムを完成し、ここに提示した後、解決にしましょう。
コード:
#include <stdio.h>
int main(void)
{
int m, n, i, j;
double buf[220][5];
FILE *text1, *text2;
text1 = fopen("input.txt", "r");
if (text1 == NULL) { printf("input file error\n"); return 1; }
text2 = fopen("output.txt", "w");
if (text2 == NULL) { printf("output file error\n"); return 2; }
for (m = 0; m < 5; m++)
for (n = 0; n < 220; n++)
if (fscanf(text1, "%lf", &buf[n][m]) != 1) goto out;
if (m == 5) { printf("too many data\n"); return 3; }
out:
for (i = 0; i < n; i++) {
for (j = 0; j <= m; j++)
fprintf(text2, " %g", buf[i][j]);
fprintf(text2, "\n");
}
for (i = n; i < 220; i++) {
for (j = 0; j < m; j++)
fprintf(text2, " %g", buf[i][j]);
fprintf(text2, "\n");
}
fclose(text2);
fclose(text1);
return 0;
}
Linux か cygwin を使っている場合、seq 1000 >input.txt で入力ファイルが作れますよ。
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月09日(水) 21:23
by シオリ
お返事ありがとうございます.
以下のように書き換え(defineを使ってみました),実行してみました.
実際にファイルに出力されるようになりましたが,2行目からimputデータと値が異なります.
また,input.txtに1199個のデータがあるのに対してoutput.txtでは26400個も出てしまいました.
コード:
#include <stdio.h>
#define row 10
#define sequence 220
int main (void)
{
int m,n,i,j;
double buf[sequence][row];
FILE *text1,*text2;
text1=fopen("dem.txt","r");
printf("読み込みファイルオープン成功\n");
if(text1==NULL)
{
printf("ファイルがありません\n");
return -1;
}
text2=fopen("output.txt","w");
printf("書き出しファイルオープン成功\n");
if(text2==NULL)
{
printf("ファイルがありません\n");
return -1;
}
for(m=0; m<sequence; m++)
{
for(n=0; n<row; n++)
{
if(fscanf(text1,"%lf",&buf[n][m])!=1) goto out;
if(m==sequence)
{
printf("too many data\n");
return -1;
}
}
}
out:
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
fprintf(text2,"%8.2f",buf[i][j]);
fprintf(text2,"\n");
}
}
for (i = n; i < sequence; i++)
{
for (j = 0; j < m; j++)
{
fprintf(text2, " %8.2f", buf[i][j]);
fprintf(text2, "\n");
}
}
fclose(text2);
fclose(text1);
return 0;
}
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月09日(水) 21:24
by シオリ
12行目のdem.txtはinput.txtの間違いです
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月10日(木) 05:11
by かずま
シオリ さんが書きました:
以下のように書き換え(defineを使ってみました),実行してみました.
実際にファイルに出力されるようになりましたが,2行目からimputデータと値が異なります.
また,input.txtに1199個のデータがあるのに対してoutput.txtでは26400個も出てしまいました.
間違いは、
- row と sequence を混同している
- for文の次の文を for文の中に押し込んでいる
- 出力の for文が 2つあるのは、列の長さが違うためなのに j < m と同じにしている
コード:
#include <stdio.h>
#define row 220 // 10 --> 220
#define sequence 10 // 220 --> 10
int main (void)
{
int m,n,i,j;
double buf[row][sequence]; // buf[sequence][row] -->
FILE *text1,*text2;
text1=fopen("input.txt","r"); // "dem.txt" --> "input.txt"
printf("読み込みファイルオープン成功\n");
if(text1==NULL)
{
printf("ファイルがありません\n");
return -1;
}
text2=fopen("output.txt","w");
printf("書き出しファイルオープン成功\n");
if(text2==NULL)
{
printf("ファイルがありません\n");
return -1;
}
for(m=0; m<sequence; m++)
{
for(n=0; n<row; n++)
{
if(fscanf(text1,"%lf",&buf[n][m])!=1) goto out;
}
}
if(m==sequence) // #
{ // #
printf("too many data\n"); // #
return -1; // #
} // #
out:
for(i=0; i<n; i++)
{
for(j=0; j<=m; j++) // j<m --> j<=m
{
fprintf(text2," %8.2f",buf[i][j]); // "%8.2f" --> " %8.2f"
}
fprintf(text2,"\n"); // #
}
for (i = n; i < row; i++) // sequence --> row
{
for (j = 0; j < m; j++)
{
fprintf(text2, " %8.2f", buf[i][j]);
}
fprintf(text2, "\n"); // #
}
fclose(text2);
fclose(text1);
return 0;
}
ファイルオープン失敗の場合も、常に
ファイルオープン成功と出力するのはいかがなもんでしょうか?
複数のデータによる確認をお願いします。
さて、元のプログラムから goto をなくすと次のようになります。
出力もひとつにまとめてみました。
コード:
#include <stdio.h>
#define ROW 220
#define COL 5
int main(void)
{
int m, n, i, j;
double buf[ROW][COL];
FILE *text1, *text2;
text1 = fopen("input.txt", "r");
if (text1 == NULL) { printf("input file error\n"); return 1; }
text2 = fopen("output.txt", "w");
if (text2 == NULL) { printf("output file error\n"); return 2; }
for (m = 0; m < COL; m++) {
for (n = 0; n < ROW; n++)
if (fscanf(text1, "%lf", &buf[n][m]) != 1) break;
if (n < ROW) break;
}
if (m == COL) { printf("too many data\n"); return 3; }
for (i = 0; i < ROW; i++) {
if (i == n) m--;
for (j = 0; j <= m; j++)
fprintf(text2, " %8g", buf[i][j]);
fprintf(text2, "\n");
}
fclose(text2);
fclose(text1);
return 0;
}
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月11日(金) 00:04
by シオリ
ありがとうございます.
指摘してくださったところについてはきちんと理解し,改善することができました.
input.txtにあるデータの個数が10個,40個,120個の場合を試しましたが,
全て同じようにoutput.txtにも出力されていました.
また,ファイルオープン失敗の際に成功と出力されないようにもしました.
コード:
#include <stdio.h>
#define ROW 220
#define COL 5
int main (void)
{
int m,n,i,j;
double buf[ROW][COL];
FILE *text1,*text2;
text1=fopen("input.txt","r");
if(text1==NULL)
{
printf("読み込みファイルがありません\n");
return -1;
}
text2=fopen("output.txt","w");
if(text2==NULL)
{
printf("書き出しファイルがありません\n");
return -1;
}
for(m=0; m<=COL; m++)
{
for(n=0; n<=ROW; n++)
{
if(fscanf(text1,"%lf",&buf[n][m])!=1) break;
}
if(n < ROW) break;
}
if(m==COL)
{
printf("too many data\n");
return -1;
}
for(i=0; i<ROW; i++)
{
if(i == n){m--;}
for(j=0; j<=m; j++)
{
fprintf(text2,"%8.2f",buf[i][j]);
}
fprintf(text2,"\n");
}
fclose(text2);
fclose(text1);
return 0;
}
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月11日(金) 00:08
by みけCAT
シオリ さんが書きました:コード:
double buf[ROW][COL];
/* 略 */
for(m=0; m<=COL; m++)
{
for(n=0; n<=ROW; n++)
{
if(fscanf(text1,"%lf",&buf[n][m])!=1) break;
}
if(n < ROW) break;
}
確保された領域の範囲外にアクセスする可能性があり、危険です。
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月11日(金) 13:54
by かずま
シオリ さんが書きました:input.txtにあるデータの個数が10個,40個,120個の場合を試しましたが,
全て同じようにoutput.txtにも出力されていました.
if(i == n){m--;} を if (i == n && --m <= 0) break; に修正してください。
あとは、みけCATさんの指摘に従い、m<=COL を m < COLになどしてください。
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月11日(金) 14:01
by かずま
かずま さんが書きました:if(i == n){m--;} を if (i == n && --m <= 0) break; に修正してください。
間違えました。
if(i == n){m--;} を if (i == n && --m < 0) break; に修正してください。
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月12日(土) 01:59
by シオリ
以下のように変更しました.
コード:
#include <stdio.h>
#define ROW 220
#define COL 5
int main (void)
{
int m,n,i,j;
double buf[ROW][COL];
FILE *text1,*text2;
text1=fopen("input.txt","r");
if(text1==NULL)
{
printf("読み込みファイルがありません\n");
return -1;
}
text2=fopen("output.txt","w");
if(text2==NULL)
{
printf("書き出しファイルがありません\n");
return -1;
}
for(m=0; m<COL; m++)
{
for(n=0; n<ROW; n++)
{
if(fscanf(text1,"%lf",&buf[n][m])!=1) break;
}
if(n < ROW) break;
}
if(m==COL)
{
printf("too many data\n");
return -1;
}
for(i=0; i<ROW; i++)
{
if(i == n && --m < 0)break;
for(j=0; j<=m; j++)
{
fprintf(text2,"%8.2f",buf[i][j]);
}
fprintf(text2,"\n");
}
fclose(text2);
fclose(text1);
return 0;
}
また,行列に格納したのち,その行列のまま出力するにはどのようにすればよいですか?
現在は1列のまま出力されているので,n行m列のように表示させたいです.
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月12日(土) 06:54
by かずま
シオリ さんが書きました:
また,行列に格納したのち,その行列のまま出力するにはどのようにすればよいですか?
現在は1列のまま出力されているので,n行m列のように表示させたいです.
入力データは、何個ですか?
入力データが 220個の場合は、220行 1列になります。
入力データが 1000個の場合は、220行 5列になります。ただし、
最初の 120行は 5列ですが、121~220行目は 4列になります。
1000 = 220 x 4 + 120 = 120 x 5 + 100 x 4 だから当然です。
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月16日(水) 16:14
by シオリ
かずま さんが書きました:シオリ さんが書きました:
また,行列に格納したのち,その行列のまま出力するにはどのようにすればよいですか?
現在は1列のまま出力されているので,n行m列のように表示させたいです.
入力データは、何個ですか?
入力データが 220個の場合は、220行 1列になります。
入力データが 1000個の場合は、220行 5列になります。ただし、
最初の 120行は 5列ですが、121~220行目は 4列になります。
1000 = 220 x 4 + 120 = 120 x 5 + 100 x 4 だから当然です。
失礼しました,私の勘違いです.
220行n列ではなく,n行220列と表示させたかったのでした.
Re: ファイルから読み込んだ値を配列に格納し,出力する
Posted: 2015年12月16日(水) 16:19
by シオリ
また,データを縦に並べるのではなく,スペースで区切り,横に並べていきたいのですがどのようにすればよいですか?
1 2 3 4 5 … 220
221 222 223 …
このように並べていきたいです.