←検索窓の楽しみ方
  ショッピングモール  掲示板ランキング


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.3440

ファイル操作:書き込み+読み込み
投稿者---C学習者(2005/02/16 21:17:37)


ファイル操作について質問です。
“峭罅∋疚勝給与、評価をキーボードから入力し(例:3人分)変数に格納。
▲侫.ぅ襦member.dat)に書き込み。
ファイルから<別の変数に読み出して>表示する。
が順序ですが、の意味がよくわかりません。
 テキストを何冊か見ながら下のソースを作りましたが、やはりがうまくいっていないので正しい表示ができません。
 どなたがアドバイスをいただけませんか?


#include<stdio.h>
#include<stdlib>
#define N 3

int main(void){

    FILE *filepnt;
    char filename[80];
    int no[N];
    char name[N][80];
    int salary[N];
    //char point[N];
        
    int i,j; int  a,b; char c[80];

    /*ファイルエラーチェック*/  
    if((filepnt = fopen("member","a+")) == NULL){
        printf("file open error\n");
        exit(EXIT_FAILURE);
    }

    /*no,name,salaryをkeyboad入力,変数に格納*/  
    for(i=0;i<N;i++){
     printf("no >");     scanf("%d",&a); no[i]=a;      
     printf("name >");   gets(c);  name[i]=c;
     printf("salary >"); scanf("%d",&b); salary[i]=b;  
     //gets("point >");  puts(point[i]);    
    }
    
    /*ファイルに書き込むループ*/
    for(j=0;j<N;j++){
     fprintf(filepnt,"%d %s %d \n",no[j],name[j],salary[j]/*,point[j]*/);
    }

    /*上記ファイルを読み込んで出力する(表示)*/
    printf(" no     name        salary   point\n");
    while((fscanf(filepnt,"%d %s %d ",&no,name,&salary/*,point*/)) != EOF){
        printf("%5d %-15s %5d  \n",no,name,salary/*,point*/);
    }

    fclose(filepnt);

    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイル操作:書き込み+読み込み 3441 RiSK 2005/02/16 22:50:02
<子記事> Re:ファイル操作:書き込み+読み込み 3447 Craft 2005/02/17 01:55:01


No.3441

Re:ファイル操作:書き込み+読み込み
投稿者---RiSK(2005/02/16 22:50:02)


#include <stdio.h>
#define N 3
#define FILE_NAME "member.dat"
typedef struct {
    int no;
    char name[32];
    int salary;
    int grade;
} MAN;
void in(MAN * man, unsigned n) {
    unsigned i;
    for (i = 0; i < n; ++i) {
        printf("no     >"); scanf("%d", &man[i].no);
        printf("name   >"); scanf("%32s", man[i].name);
        printf("salary >"); scanf("%d", &man[i].salary);
        printf("grade  >"); scanf("%d", &man[i].grade);
    }
}
void out(const MAN * man, unsigned n) {
    unsigned i;
    for (i = 0; i < n; ++i) {
        printf("no     > %d\n", &man[i].no);
        printf("name   > %s\n", &man[i].name);
        printf("salary > &d\n", &man[i].salary);
        printf("grade  > %d\n", &man[i].grade);
    }
}
int main(void) {
    FILE * f;
    MAN man_w[N], man_r[N];
    // 1

    in(man_w, N);

    // 2

    if ((f = fopen(FILE_NAME, "w")) == NULL) return 1;
    if (fwrite(man_w, sizeof(MAN), N, f) != N) {fclose(f); return 1;}
    fclose(f);

    // 3

    if ((f = fopen(FILE_NAME, "r")) == NULL) return 1;
    if (fread(man_r, sizeof(MAN), N, f) != N) {fclose(f); return 1;}
    fclose(f);

    out(man_r, N);

    return 0;
}



この投稿にコメントする

削除パスワード

No.3444

Re:ファイル操作:書き込み+読み込み
投稿者---南野骨茶(2005/02/17 00:20:59)


隣でもお世話になっております。

        printf("salary > &d\n", &man[i].salary);


ここの&dは%dが正しいであろう、ということはわかったのですが、
これ以外に、私のところではfread()の戻り値が本来あるべき3ではなく
2になってしまい、out()を実行せずに終了してしまっています。

RiSKさんのところでは大丈夫ですか?


この投稿にコメントする

削除パスワード

No.3446

Re:ファイル操作:書き込み+読み込み
投稿者---Craft(2005/02/17 01:34:13)


>これ以外に、私のところではfread()の戻り値が本来あるべき3ではなく
>2になってしまい、out()を実行せずに終了してしまっています。

こちらでも試しましたが、outが実行されないケースは発生しませんでした。

ほかにも、&d 以外に、outのprintfに渡してる内容が、&付きになっているので、表示が全部ポインタ値になってしまってますね。

void out(const MAN * man, unsigned n) {
    unsigned i;
    for (i = 0; i < n; ++i) {
        printf("no     > %d\n", &man[i].no);
        printf("name   > %s\n", &man[i].name);
        printf("salary > &d\n", &man[i].salary);
        printf("grade  > %d\n", &man[i].grade);
    }
}



この投稿にコメントする

削除パスワード

No.3449

Re:ファイル操作:書き込み+読み込み
投稿者---RiSK(2005/02/17 10:47:21)


ごめんなさい。テスト0で即レスしました。
バギーなコードでしたね…
# 可変数引数の関数はコンパイルエラーが出ないから怖いッス

>>これ以外に、私のところではfread()の戻り値が本来あるべき3ではなく
>>2になってしまい、out()を実行せずに終了してしまっています。
>
>こちらでも試しましたが、outが実行されないケースは発生しませんでした。

同じく正常 3 が返ります。"wb" "rb" でどうでしょう?
# 当方 WinXP VC6 です

>ほかにも、&d 以外に、outのprintfに渡してる内容が、&付きになっているので、表示が全部ポインタ値になってしまってますね。

そうでした。ご指摘に感謝。
void out(const MAN * man, unsigned n) {
    unsigned i;
    for (i = 0; i < n; ++i) {
        printf("no     > %d\n", man[i].no);
        printf("name   > %s\n", man[i].name);
        printf("salary > %d\n", man[i].salary);
        printf("grade  > %d\n", man[i].grade);
    }
}



この投稿にコメントする

削除パスワード

No.3447

Re:ファイル操作:書き込み+読み込み
投稿者---Craft(2005/02/17 01:55:01)


アドバイスをしてほしいとのことなので、C学習者さんの掲示ソースにあまり手を入れないで解説します。
RiSKさんのソースは、構造体と関数を使ってわかりやすくしたものになります。

現ソースでうまくいかないと思われる部分を青でなおしました。

nameの入力部分。
gets()は、直前のscanf()の改行を拾ってしまうので、おそらくうまく動いていないと思います。

他がscanf()で入力方法をそろえていますので、scanf()に置き換えた方がいいです。
あと、中間変数を経由して配列にいれていますが、直接scanf()から入力できますので、配列に直接取り込んでいいと思います。


入力データが表示されない部分。

fscanfでデータを読もうとしていますが、"a+"で書き込んだファイルは、書き込んだ直後には常にファイルの最後を示しています。
ファイルの最初から読めるように、一度ファイルを閉じて、開き直す必要があります。
また、fscanf()で読み込む先が、配列をさしているにもかかわらず、要素が指定されていないので、正しく読み取れません。
配列に取り込みたい場合は要素を指定する必要があります。

fscanf()は、空白を読み飛ばすので、フォーマット指定内の半角空白は期待した効果を発揮しません。
フォーマットを指定しても、fprintf()の反対にはならないので注意しましょう。

#include <stdio.h>
#include <stdlib.h>
#define N 3

int main(void){

    FILE *filepnt;
    char filename[80];
    int no[N];
    char name[N][80];
    int salary[N];
    //char point[N];
        
    int i,j;
    int a,b;
    char c[80];

    /*ファイルエラーチェック*/  
    if((filepnt = fopen("member","a+")) == NULL){
        printf("file open error\n");
        exit(EXIT_FAILURE);
    }

    /*no,name,salaryをkeyboad入力,変数に格納*/  
    for(i=0;i<N;i++){
       printf("no >");     scanf("%d",&no[i]);
       printf("name >");   scanf("%s",name[i]); 
       printf("salary >"); scanf("%d",&salary[i]);
       //gets("point >");  puts(point[i]);
    }

    /*ファイルに書き込むループ*/
    for(j=0;j<N;j++){
       fprintf(filepnt,"%d %s %d \n",no[j],name[j],salary[j]/*,point[j]*/);
    }
    fclose(filepnt);

    /*ファイルエラーチェック*/  
    if((filepnt = fopen("member","r")) == NULL){
        printf("file open error\n");
        exit(EXIT_FAILURE);
    }

    /*上記ファイルを読み込んで出力する(表示)*/
    printf(" no     name        salary   point\n");
    while((fscanf(filepnt,"%d%s%d",&no[0],name[0],&salary[0]/*,point*/)) != EOF){
        printf("%5d %-15s %5d  \n",no[0],name[0],salary[0]/*,point*/);
    }

    fclose(filepnt);

    return 0;
}




この投稿にコメントする

削除パスワード

No.3452

Re:ファイル操作:書き込み+読み込み
投稿者---C学習者(2005/02/18 12:49:26)


>みなさんありがとうございます。
 scanf/getsのことファイルのopenとclose、fscanf・fprintfなど大変参考になりました。ありがとうございます。
 craftさんに質問です。
 名前入力で、tanaka taro と空白を含んだ入力をしたいんですが。その場合gets()を使うことはわかるのですが他の3個も(//のpointも含む)揃えなけらばならないのですよね。その場合出力する時は(no、salary)atoiで文字列を数値に変換すればいいのですかね?
 また、ファイルに書き込み後、ファイルを再び開き表示する(コマンドプロンプトにおいて)ところですが、実行しても表示されないのはなぜかわからないのですが、教えていただけないでしょうか?
 
 自分にとって(工夫することが)なかなか難しいので苦労しています。


この投稿にコメントする

削除パスワード

No.3455

Re:ファイル操作:書き込み+読み込み
投稿者---Craft(2005/02/19 01:37:43)


>>みなさんありがとうございます。
> scanf/getsのことファイルのopenとclose、fscanf・fprintfなど大変参考になりました。ありがとうございます。
> craftさんに質問です。
> 名前入力で、tanaka taro と空白を含んだ入力をしたいんですが。その場合gets()を使うことはわかるのですが他の3個も(//のpointも含む)揃えなけらばならないのですよね。その場合出力する時は(no、salary)atoiで文字列を数値に変換すればいいのですかね?
> また、ファイルに書き込み後、ファイルを再び開き表示する(コマンドプロンプトにおいて)ところですが、実行しても表示されないのはなぜかわからないのですが、教えていただけないでしょうか?

すいません。うっかりしてました。
fscanfの仕様をかんちがいしていました。
空白は読み飛ばすのではありません。%dであれば変換できないところまで数値化する、なのでたまたま空白を読まなかっただけでした。

いろいろためしてみましたが、空白の影響でデータによってfscanfが変換に失敗したりするので、区切りに空白があったり、区切り文字に該当する文字が入力される可能性があるファイルを読むのは結構難しいです。

whileのところを次のようにかえてみてください。
"%1c"で、c[0]に空白を読み込ませることで、区切り文字を処理しています。
名前に空白をつかうとダメです。
    while((fscanf(filepnt,"%d%1c%s%1c%d",&no[0],&c[0],name[0],&c[0],&salary[0]/*,point*/)) != EOF){
        printf("%5d %-15s %5d  \n",no[0],name[0],salary[0]/*,point*/);
    }



複数データから構成される定型書式のデータを書く、あるいは読む場合は、慣れないうちは無理に関数にする必要はないので、RiSKさんのサンプルソースにあるように構造体を使う方が確実です。
ためしてみてください。

もうひとつの、gets()を使うために、scanf()とgets()を両立させる方法をかいておきます。
scanf()にある、"%d%*c"というのがポイントで、"%d"で数値を取り込んだ後、"%*c"で"%d"に変換にできなかった文字を全て捨てる、という意味になります。
先行する書式が"%s"でも大丈夫だと思いますが、確認できていません。

#include <stdio.h>

int main(void){
    int d;
    char s[50];

    printf("in:d=");
    scanf( "%d*c", &d );
    printf("in:s=");
    scanf( "%s", s );
    printf("out: d=%d,s=%s\n", d, s);

    return 0;
}




この投稿にコメントする

削除パスワード

No.3456

Re:ファイル操作:書き込み+読み込み
投稿者---C学習者(2005/02/19 22:01:33)


>craftさんありがとうございます。表示が無限表示みたいな感じでやっぱりだめですね。(でももう大丈夫です)

>>RiSKさんのソースは、構造体と関数を使ってわかりやすくしたものになります。
 >RISKさんのソース(上から2番目の)について見てみました。基本的なファイル書き込みや読み出し表示などはわかりのですが個々の箇所でわからない点があったので、どなたか教えていただけませんか。

 
if ((f = fopen(FILE_NAME, "w")) == NULL) return 1;
    if (fwrite(man_w, sizeof(MAN), N, f) != N) {fclose(f); return 1;}
    fclose(f);


 /*質問1:ここの文ですが全体でなにをしているかはわかります。しかしreturn 1の辺がよくわかりません。これは何を意味しているのでしょうか?*/
 
/*質問2:名前を入力する時、なぜ空白が入るとうまくいかないんでしょうか(構造体ならうまくいくと思ったのですが)。(いれると、次のsalary>poin>noとおかしい)*/
/*質問3:表示するとき以下の書式でバランスしたいのにうまくいかないのはどうすればいいのでしょうか。\tを使いましたが。*/
void out(const MAN * man, unsigned n) {
    unsigned i;
    printf("no       name            salary point\n");
    for (i = 0; i < n; ++i) {
        printf("%d\t",man[i].no);
        printf("%s\t" , man[i].name);
        printf("%d\t" , man[i].salary);
        printf("%d\t", man[i].grade);
    printf("\n");    


/*最後に私は学習して1ヶ月もたっていないためこのソースを見て大体は何をしているのかなぐらいはわかります。 ただファイル操作・構造体・関数・ポインタ・他など組み合わさってくると少し複雑になりわからない文も増えてきます。
 ですので、もしよろしかったらここはわかりづらいのではないかという箇所にコメントを付けていただけると今後ともありがたい次第です。親切なかたよろしくお願いします。*/



この投稿にコメントする

削除パスワード

No.3465

Re:ファイル操作:書き込み+読み込み
投稿者---KING・王(2005/02/20 22:21:22)


> 
if ((f = fopen(FILE_NAME, "w")) == NULL) return 1;
    if (fwrite(man_w, sizeof(MAN), N, f) != N) {fclose(f); return 1;}
    fclose(f);


> /*質問1:ここの文ですが全体でなにをしているかはわかります。しかしreturn 1の辺がよくわかりません。これは何を意味しているのでしょうか?*/
> 

fopen()やfwrite()で失敗したときにエラーとして1を返しているのだと思います。(おそらく成功の場合は0を返すようにしているはずです。)

>/*最後に私は学習して1ヶ月もたっていないためこのソースを見て大体は何をしているのかなぐらいはわかります。 ただファイル操作・構造体・関数・ポインタ・他など組み合わさってくると少し複雑になりわからない文も増えてきます。
> ですので、もしよろしかったらここはわかりづらいのではないかという箇所にコメントを付けていただけると今後ともありがたい次第です。親切なかたよろしくお願いします。*/

初心者なら、なおさら自分で調べて、コメントをつけてみた方が勉強になると思います。
その上で、自分ではこのように考えたが、この考え方は間違っていますか?
というような質問をすれば、レスが得られ易いと思いますよ。
(努力の姿勢を見せないと丸投げとみなされ、レスがもらえない、または注意を受けます。)


この投稿にコメントする

削除パスワード

No.3466

Re:ファイル操作:書き込み+読み込み
投稿者---RiSK(2005/02/20 22:43:49)


>RISKさんのソース(上から2番目の)について見てみました。

であれば私の投稿に対してレスしてください。今まで気付きませんでした。

>質問1:ここの文ですが全体でなにをしているかはわかります。しかしreturn 1の辺がよくわかりません。これは何を意味しているのでしょうか?

# return 1 ではなく return 1; です。
エラーですので main 関数を抜けます。
その時,読んで字のごとく 1 を返します。
main関数は正常終了の時 0,異常終了の時 非0 を返すようにします。

>質問2:名前を入力する時、なぜ空白が入るとうまくいかないんでしょうか(構造体ならうまくいくと思ったのですが)。

scanf の仕様です。%s は空白文字までの文字列を読み込みます。
そのため空白文字は読み込めません。

ちなみに改行文字 \n も空白文字の一つです。
もし空白文字まで読み込んでしまったら,
終了する術が無く永遠に読み込むことになってしまいます。
# っていうのは大げさ

> いれると、次のsalary>poin>noとおかしい)

仮に "hoge foo" と入力したとしましょう。
初めの %s により hoge が man[i].name に読み込まれます。
その時, foo がバッファに残ります。
続いて 次の行で %d で man[i].salary へ読み込もうとします。
ところが foo は数字でないので scanf は失敗して次の行へいきます。
まだ foo がバッファに残っています。
salary > が出力されます。
続いて 次の行で %d で man[i].grade へ読み込もうとします。
ところが foo は数字でないので scanf は失敗して次の行へいきます。
grade > が出力されます。
こうして in 関数を抜けてしまうわけです。

>質問3:表示するとき以下の書式でバランスしたいのにうまくいかないのはどうすればいいのでしょうか。\tを使いましたが。

大抵8文字分だと推測していますが,
タブ幅って何文字分か規格で決まっているのでしょうか?

まぁ,どう「バランス」を取りたいのか分かりませんが,
# ってか,どう「うまくいかない」のかも分からない
次のようにしてみてください。
んで,期待する書式と現在の書式と,これでOKか,などレス下さい。
void out(const MAN * man, unsigned n) {
    unsigned i;
    printf("no       name            salary point\n");
    for (i = 0; i < n; ++i) {
        printf("%8d ", man[i].no);
        printf("%-15s ", man[i].name);
        printf("%6d ", man[i].salary);
        printf("%5d\n", man[i].grade);
    }
}


>最後に私は学習して1ヶ月もたっていないためこのソースを見て大体は何をしているのかなぐらいはわかります。 ただファイル操作・構造体・関数・ポインタ・他など組み合わさってくると少し複雑になりわからない文も増えてきます。

それはどういう組み合わせ?

> ですので、もしよろしかったらここはわかりづらいのではないかという箇所にコメントを付けていただけると今後ともありがたい次第です。親切なかたよろしくお願いします。

C学習者さんが「わかりづらいの」はどれ? 何?
なぜそれをこちらが推測せねばならんのじゃ?

具体的な質問でなければ具体的な回答は期待できんよ。
うーん。親切に答えるなら K&R なり,規格書なり買って読むように。
と言っておきます。

# 最後に
# RISK ではなく RiSK です (^^;;


この投稿にコメントする

削除パスワード

No.3481

Re:追加質問です。
投稿者---C学習者(2005/02/23 19:09:49)


>先日は申し訳ありませんでした。

>>質問2:名前を入力する時、なぜ空白が入るとうまくいかないんでしょうか>>
 そこで私はgetsでキー入力し、出力の時にatoiを使って文字列を数字変換と考えました。しかし、member.datファイルの書き込み内容もおかしいですし、ファイルから別の変数に読み出して表示するところもおかしいのです。(1・2行目のデータが2回出力されるという症状)
 いったいどうすればよろしんでしょう?(過去ログ・当サイトのscanf/getsをみてもなかったので。もしかしたら見落としているかもしれません。)

>>質問3:表示するとき以下の書式でバランスしたいのにうまくいかないのはどうすればいいのでしょうか。
 いい忘れましたが書式は、番号5桁、氏名20字以内、給与5桁、評価1桁です。(あと間隔は2マス空けるくらいです。)いちおう自分では以下のようにしました。(前者はオッケーだとおもいます。)が、no name salary pointという題が入れた名前によってずれてしまいます。

サンプル**
void in(MAN * man, unsigned n) {
    unsigned i;
    for (i = 0; i < n; ++i) {
        printf("no     >"); gets(man[i].no);
        printf("name   >"); gets(man[i].name);
        printf("salary >"); gets(man[i].salary);
        printf("grade  >"); gets(man[i].grade);
    }
}
void out(const MAN * man, unsigned n) {
    unsigned i;int j,k;
    printf("no       name         salary point\n");
    for (i = 0; i < n; ++i) {
        j = atoi(man[i].no);    printf("%5d ",j);
                    printf("%-20s ", man[i].name);
        k = atoi(man[i].salary);printf("%5d ",k);
                    printf("%s\n", man[i].grade);
    }


 


**質問4ですが、一番最初の質問()で(ファイル書き込み後)ファイルから別の変数に読み出して表示するというものがありましたが、別の変数に読み出しての箇所はどこだったでしょうか?聞き忘れていましたので。間違っているかもしれませんが、fwrite(man_w, )とfread(man_r, )でしょうか?
 
**質問5ですがファイルが存在しない場合には自動的に作成し、あれば上書きするというモードにしたいのですが、"wb","rb"、"w+""r+"で試したのですがそれぞれファイルをメモ帳で開くと暗号みたいになっていました。どう操作すればいいんでしょうか?(テキストで調べましたがバイナリファイルも含めていまいち?です)
 
 *質問が多すぎて申しわけないです。
 




この投稿にコメントする

削除パスワード

No.3493

Re:再・RiSKさんへ
投稿者---C学習者(2005/02/25 19:29:00)


>>先日は申し訳ありませんでした。どうしてもわからないので悪いと思いながら、再び質問させていただきました。
 ですので、もしよろしかったらもう一度ご回答お願いできますか?
>
>>>質問2:名前を入力する時、なぜ空白が入るとうまくいかないんでしょうか>>
> そこで私はgetsでキー入力し、出力の時にatoiを使って文字列を数字変換と考えました。しかし、member.datファイルの書き込み内容もおかしいですし、ファイルから別の変数に読み出して表示するところもおかしいのです。(1・2行目のデータが2回出力されるという症状)
> いったいどうすればよろしんでしょう?(過去ログ・当サイトのscanf/getsをみてもなかったので。もしかしたら見落としているかもしれません。)
>
>>>質問3:表示するとき以下の書式でバランスしたいのにうまくいかないのはどうすればいいのでしょうか。
> いい忘れましたが書式は、番号5桁、氏名20字以内、給与5桁、評価1桁です。(あと間隔は2マス空けるくらいです。)いちおう自分では以下のようにしました。(前者はオッケーだとおもいます。)が、no name salary pointという題が入れた名前などによってずれてしまいます。
>
サンプル**

void in(MAN * man, unsigned n) {
    unsigned i;
    for (i = 0; i < n; ++i) {/*k・lは定義済みとしています*/
        k=atoi(man[i].no);printf("no     >"); gets(man[i].no);
        printf("name   >"); gets(man[i].name);
        l=atoi(man[i].salary)printf("salary >"); gets(man[i].salary);
        printf("grade  >"); gets(man[i].grade);
    }
}
void out(const MAN * man, unsigned n) {
    unsigned i;int j,k;
    printf("no       name         salary point\n");
    for (i = 0; i < n; ++i) {
        j = atoi(man[i].no);    printf("%5d ",j);
                    printf("%-20s ", man[i].name);
        k = atoi(man[i].salary);printf("%5d ",k);
                    printf("%s\n", man[i].grade);
    }



>
>
>**質問4ですが、一番最初の質問()で(ファイル書き込み後)ファイルから別の変数に読み出して表示するというものがありましたが、別の変数に読み出しての箇所はどこだったでしょうか?(どこかよくわからなかったので)間違っているかもしれませんが、fwrite(man_w, )とfread(man_r, )の箇所と私は思ったのですが。
> 
> 
>
> 
>
>




この投稿にコメントする

削除パスワード

No.3495

Re:再・RiSKさんへ
投稿者---RAPT(2005/02/25 23:17:44)


> 質問3
文字列の部分表示については次の簡単なサンプルコードを実行し
結果を比較してみてください。

#include <stdio.h>

int main()
{
    const char *str = "1234567890";
    printf("%-5s\n", str);
    printf("%-.5s\n", str);
    return 0;
}


> 質問5ですがファイルが存在しない場合には自動的に作成し、あれば上書きする
"w"


それから、掲示板の使い方ですが、引用部分と自分の述べる言葉の部分とを
明確に区別できるように記述してください。どこからどこまでが質問なのか
分かりにくいです。また、現在のあなたのソースコードを提示してください。
(無論、HTML変換ツールを使って綺麗に整形してくださいね。)
あと、無用な引用はやめましょう。<見難いから。



この投稿にコメントする

削除パスワード

No.3497

Re:再・RiSKさんへ
投稿者---C学習者(2005/02/26 11:00:44)


 *ラプトさん率直なご返答ありがとうございます。
 先日3時間くらい試行錯誤した結果ほぼソースを解読でき、また質問についてもほぼ解決できました。
 皆さんに頼りすぎて、自分で長い時間考えることを怠ったことを反省しております。ですのでこれからもよろしくお願いします。
 以下がRiSKさんがご提示してくださったソースを自分なりにしたものです。


#include <stdio.h>
#define N 3/*記号定数(配列要素数)*/ /*マクロ定義(下も)*/
#define FILE_NAME "member.dat"/*文字列の置き換え(ファイル名)*/


typedef struct  {/*typedef宣言と構造体宣言の一体化(構造体名の省略)*/
    int no;
    char name[20];
    int salary;
    char point[1];
} MAN;

void in(MAN * man, unsigned n);/*プロトタイプ宣言*/
void out(const MAN * man, unsigned n);

int main(void) {
    FILE * f;
    MAN man_w[N], man_r[N];/*構造体配列の宣言*/
    // 1


    in(man_w, N);/*配列の先頭アドレスと定数Nをin関数の実引数に*/

    // 2

    /*変数fを使って、FILE_NAMEを書き込み用にファイルオープンする*/
    if ((f = fopen(FILE_NAME, "w+")) == NULL) return 1;
    /*ブロック単位の出力(構造体配列man_wをN個文書き込む)、構造体を一度に書く*/
    if (fwrite(man_w, sizeof(MAN), N, f) != N) {fclose(f); return 1;}
    fclose(f);

    // 3

    /*変数fを使って、FILE_NAMEを読み込み用にファイルオープンする*/
    if ((f = fopen(FILE_NAME, "r+")) == NULL) return 1;   /*return 1はエラー*/
    /*ブロック単位の入力(構造体配列man_rをN個読み込む)、構造体を一度に読む*/
    if (fread(man_r, sizeof(MAN), N, f) != N) {fclose(f); return 1;}
    fclose(f);

    out(man_r, N);

    return 0;
}


void in(MAN * man, unsigned n) {/*第一引数はアドレスを受けるのでポインタでやりとり*/
    unsigned i;
    printf("no(5桁),name(ローマ字20字以内),salary(5桁),point(a/b/c)で入力して下さい!\n");
    for (i = 0; i < n; ++i) {
       printf("no     >");  scanf("%d%*c", &man[i].no);/*数字を読み込んだ後%*cで\nを削除*/
        printf("name   >"); gets(man[i].name);
        printf("salary >"); scanf("%d", &man[i].salary);
        printf("point  >"); scanf("%s", &man[i].point);
    }
}


void out(const MAN * man, unsigned n) {
    unsigned i;
    printf("no       name           salary point\n");
    for (i = 0; i < n; ++i) {
        printf("%5d ", man[i].no);/*体裁に合わせた出力*/
        printf("%-20s ", man[i].name);
        printf("%5d ", man[i].salary);
        printf("%s\n", man[i].point);
    }
}



この投稿にコメントする

削除パスワード

No.3499

gets関数について
投稿者---言羊糸田言殳言十(2005/02/26 16:26:38)


> 以下がRiSKさんがご提示してくださったソースを自分なりにしたものです。

私は、gets関数を使っているところがどうも気になります。
他の方々はそういうことはありませんか?

gets関数は入力データの長さをチェックしないため、入力データによっては
他の変数用に割り当ててある領域を破壊することがある、
だから使ってはいけない、と教わってきました。


この投稿にコメントする

削除パスワード

No.3500

Re:gets関数について
投稿者---shu(2005/02/26 17:15:09)


>gets関数は入力データの長さをチェックしないため、入力データによっては
>他の変数用に割り当ててある領域を破壊することがある、
>だから使ってはいけない、と教わってきました。

使っては行けないことを知るために、
用意されたものと思って使えばよい。

gets()にしろscanf()にしろ、
なるべく早い段階で、
メモリ破壊や暴走などの怖さを、
味わってもらうには、すごく大切な関数だと考えます。

実用性はともかく、
勉強、テスト、実験には役に立ってる。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity