質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

Q&A

解決済

1回答

1331閲覧

C言語 mallocを用いた配列のソーティングプログラム

Kassy11

総合スコア26

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

0グッド

0クリップ

投稿2019/05/22 12:28

編集2019/05/22 12:46

現在C言語で、ソーティングプログラムを以下のように実装しています。
①main関数でコマンドライン引数を用いて入力ファイル名及び出力ファイル名を受け取る
(なお入力ファイルの最初には自身を除くデータの個数を記録しておき、2番目以降の要素をソートする)
②input_file関数で、入力ファイルをオープンし、まずデータの個数を読み取りdata_sizeに格納する
③mallocを用いて、size_of(int)*data_size分の動的メモリを確保する
④2番目以降の要素を読み取り配列に格納し、ソートを行ない出力ファイルに書き込む
(sort_func関数/output_file関数)

このような処理の流れで実装しているのですが、最終的な出力ファイルの最後の要素に以下のように不明な数字(アドレス??)が紛れ込みます。
mallocを用いずに要素数を固定した配列でinput_fileを書き換えると変な数字が紛れ込まず処理が終了するため、input_file内のコードに問題があるかと思います。

コードのどの部分に問題があるのかわからないため、質問させていただきます。
よろしくお願いします。

C言語

1#include <stdio.h> 2#include <stdlib.h> 3 4static int *number; 5 6int input_file(char *input_name); 7void output_file(char *output_name,int n, int number[]); 8void sort_func(int number[],int n); 9 10int main(int argc,char *argv[]) {/*agrv[1]は入力ファイル名:最初にはデータの個数を記録しておくものとする、[2]は出力ファイル名*/ 11 int n; 12 13 if(argc != 3){/*ファイルは2つのみ*/ 14 printf("入力ファイルと出力ファイルを指定してください.\n"); 15 return 1; 16 } 17 18 n = input_file(argv[1]); 19 sort_func(number,n); 20 output_file(argv[2],n,number); 21 22 return 0; 23} 24 25int input_file(char *input_name){/*入力ファイル名を受け取り、ファイルをオープンして読み込み、配列に格納し、配列の個数を返す*/ 26 int count = 1, temp,data_size; 27 28 FILE *fp; 29 if((fp = fopen(input_name,"r")) == NULL){ 30 printf("入力ファイルをオープンできませんでした。\n"); 31 } 32 33 fscanf(fp,"%d",&data_size); /*入力ファイルに最初にあるデータの個数を読みとる*/ 34 printf("データの個数:%d",data_size); 35 36 if((number=(int*)malloc(sizeof(int)*data_size)) == NULL){ 37 printf("メモリ領域を確保できませんでした。\n"); 38 exit(0); 39 } 40 41 42 while(fscanf(fp,"%d",&temp)==1){/*二番目の要素から読み込み、配列に格納する*/ 43 number[count++] = temp; 44 } 45 printf("入力ファイルの処理完了。\n"); 46 fclose(fp); 47 48 return count; 49} 50 51 52void output_file(char *output_name, int n, int number[]){/*出力ファイル名を受け取り、ファイルをオープンして、配列の内容をファイルに書き込む*/ 53 FILE *fp; 54 int i; 55 if((fp = fopen(output_name,"w")) == NULL){ 56 printf("出力ファイルをオープンできませんでした。\n"); 57 }else{ 58 printf("書き込みに成功しました。\n"); 59 for(i=0;i<n;i++){ 60 fprintf(fp,"%d ",number[i]); 61 } 62 } 63 fclose(fp); 64 free(number); 65} 66 67void sort_func( int number[], int n ) 68{ 69 int k,m,x,y; 70 71 for( k=1; k<n; ++k ) 72 { 73 x = number[k]; 74 if( number[k-1] <= x )continue; 75 76 for( m=0; m<k; ++m ) 77 { 78 if( number[m] >= x )break; /*mを見つけたらループ抜ける*/ 79 } 80 for( y=k; y>m; --y ) /*要素をずらしていく*/ 81 { 82 number[y] = number[y-1]; 83 } 84 number[m] = x; 85 } 86 printf("ソートを完了しました。\n"); 87} 88 89

ファイル内容

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2019/05/22 12:38

> 以下のように不明な数字(アドレス??)が紛れ込みます。 「以下」とはドレのことでしょうか.
Kassy11

2019/05/22 12:47

画像を追加し忘れていました。
guest

回答1

0

ベストアンサー

デバッグ環境はありますか?
読み込みのループ(number[count++]=temp)で止めて、countを確認しましょう。
配列の添え字は0始まりですよ。

投稿2019/05/22 12:40

Q71

総合スコア995

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kassy11

2019/05/22 12:51

count = 0にすると解決しました。 単純なミスで申し訳ありません。 しかし、はじめにfscanfをしてから次にfscanfをすると二番目の要素から読み込まれるのはなぜなのでしょうか?? fscanf(fp+1,"%d",&temp)なのではないかとも思います。
Q71

2019/05/22 13:09

いえ、よくあるミスです。そして、コードレビューで見つけられるミスです。 次に読むべき箇所を示すポインタが進むからです。
jimbe

2019/05/23 02:08 編集

fp は `FILE *fp` と宣言されている通り, FILE 構造体へのポインタです. FILE 構造体は, 名前はファイルそのもののように見えますが「ファイルの情報」を持つ構造体です. char* 等のように fp が直接ファイル内の位置を示すのでは無く, FILE 構造体内に現在位置(Q71さんの言われる「読むべき箇所を示すポインタ」)が保持されていて, その値が fscanf によって自動的に進められているとイメージされると良いかと思います.
Kassy11

2019/05/23 00:48

なるほど、了解しました。 お二方ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問