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


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

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

 詳しくはこちら


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

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


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

No.3874

ファイル読み出し・編集・画面出力
投稿者---シグウィン(2005/06/02 21:14:41)


こんばんわ。シグウィンです。
早速質問です。
 題名のとおりファイルをオープンしてファイルを一行ずつ読み出して、編集して一行ずつコンソールに出力するログラムです。最後にファイルを閉じる!
 わからない点は、編集の箇所です。
 メモ帳にno・氏名・性別・年・組が「,」で区切られています。
 それが1行で15行あります。
 氏名以外は数字ですが、ファイルを読み込んだ後の編集で性別は1・2(それぞれ男・女)からman・womanに変えなければならないのですが、一行を読み込んで性別の箇所を変更できるのかなと頭を悩ませております。(プラス出力時は項目ごと適度にスペースも空けないといけないし)
 自分の予想では、isdigit()なんかの関数で判定するのかなと思ったりしたけど。
 あとやっぱりmain()のなかで編集するということは、上記の変数を宣言しないと個々の編集もできませんよね?

 一応途中までのソースを貼り付けておきます。
000: #include<stdio>
001: #include<string>
002: #include<stdlib>
003: 
004: int main(void)
005: {
006:     FILE *fp;
007:     char filename[80], ss[256];
008:     char *p;
009:     
010:     printf("ファイル名=");
011:     gets(filename);
012:     
013:     if((fp=fopen(filename,"r")) == NULL) {//ファイルをオープンする

014:         printf("ファイルをオープンできません。\n");
015:         exit(1);
016:     }
017:     while(fgets(ss,256,fp) != NULL){//一行ずつ読み込む

018:         p = strtok(ss,","); //コンマを除いた行をポインタに格納
019:         
020:         printf("%s",p);
021:         while((p=strtok(NULL,",")) != NULL)
022:             printf("%s",p);
023:     }
024:     
025:     fclose(fp);//ファイルをクローズする

026:     
027:     return 0;
028: }
029: 
030: 





この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイル読み出し・編集・画面出力 3876 elder 2005/06/02 21:26:20
<子記事> Re:ファイル読み出し・編集・画面出力 3877 まきじ 2005/06/02 21:31:43


No.3876

Re:ファイル読み出し・編集・画面出力
投稿者---elder(2005/06/02 21:26:20)


何がしたいのかよくわかりません。
入力例/出力結果例を提示してみてください。


この投稿にコメントする

削除パスワード

No.3882

入力・出力例
投稿者---シグウィン(2005/06/02 22:20:53)



>何がしたいのかよくわかりません。
>入力例/出力結果例を提示してみてください。

 大変失礼しました。 こんな感じです!
 (入力例)class.txt
200100,akagi tarou,1,1,1 //no・名前・性別・年・クラスです。
200101,kotani hanako,2,1,2 //ちなみにnoは昇順です
201010,saitou tarou,1,2,3
201011,takahara hanako,2,2,2
201012,nakahara tarou,1,1,3
201013,yagi hanako,2,1,1

(出力例)

**************************************************
学生番号   *名前       性別    年   組
200101   *kotani hanako  woman      1    2 
201010  *saitou tarou   man        2    3
201011  *takahara hanako woman      2    2
201012  *nakahara tarou  man        1    3
201013  *yagi hanako   woman      1    1
***************************************************







この投稿にコメントする

削除パスワード

No.3877

Re:ファイル読み出し・編集・画面出力
投稿者---まきじ(2005/06/02 21:31:43)


> 氏名以外は数字ですが、ファイルを読み込んだ後の編集で
性別は1・2(それぞれ男・女)からman・womanに変えなければならないのですが、
一行を読み込んで性別の箇所を変更できるのかなと頭を悩ませております。

ファイルの上書きはできないので、新たにファイルを作り、
元ファイルから、fscanf で読み込み、no・氏名・性別・年・組 を
性別を判定して、fprintf で新たな性別で書き込んで、
元ファイルを削除して、新たなファイルの名前を変更すればよいと思います。


この投稿にコメントする

削除パスワード

No.3878

Re:ファイル読み出し・編集・画面出力
投稿者---まきじ(2005/06/02 21:33:27)


>元ファイルから、fscanf で読み込み、no・氏名・性別・年・組 を

訂正:元ファイルから、fscanf で、no・氏名・性別・年・組 を読み込み、


この投稿にコメントする

削除パスワード

No.3880

返答:ファイル読み出し・編集・画面出力
投稿者---シグウィン(2005/06/02 22:16:38)


>ファイルの上書きはできないので、新たにファイルを作り、
>元ファイルから、fscanf で読み込み、no・氏名・性別・年・組 を
>性別を判定して、fprintf で新たな性別で書き込んで、
>元ファイルを削除して、新たなファイルの名前を変更すればよいと思います。

思いつきもしませんでした。ナイスアイディアですね。
ワンクッションおいてから、その後上書きですか。私も徐々にそういう考え方を身に着けていきたいですね。
 ちなみに他の方法はありませんか?ちょっとまわりくどいと思ったので。失礼者ですいません。


この投稿にコメントする

削除パスワード

No.3881

Re:返答:ファイル読み出し・編集・画面出力
投稿者---まきじ(2005/06/02 22:19:14)


> ちなみに他の方法はありませんか?

私には思い浮かばないです。


この投稿にコメントする

削除パスワード

No.3884

Re:追加質問 to まきじ殿
投稿者---シグウィン(2005/06/02 22:42:42)


 
 元のファイルから新しいファイルへ読み出して性別判定とのことでしたが、ひとつのファイルオープンでは駄目ですよね。二つあるから二つのファイルオープンですかね?(それに対応してファイルクローズもですね。)
 
 また新しいファイルでの処理後もとのファイルは削除されるといっておられましたが少し意味がわかりませんでした。それは上書きされた結果消えるということですか、それともソース上でそう指示するということですか?


この投稿にコメントする

削除パスワード

No.3885

Re:追加質問 to まきじ殿
投稿者---まきじ(2005/06/02 23:01:13)


> 
> 元のファイルから新しいファイルへ読み出して性別判定とのことでしたが、ひとつのファイルオープンでは駄目ですよね。二つあるから二つのファイルオープンですかね?(それに対応してファイルクローズもですね。)

読み込むファイルと書き込み用のファイルをオープンする必要があります。
処理が終われば、当然それぞれを fclose してください。
 
> また新しいファイルでの処理後もとのファイルは削除されるといっておられましたが少し意味がわかりませんでした。

ファイルの削除には、remove という関数があります。
ファイル名の変更には、rename という関数があります。


この投稿にコメントする

削除パスワード

No.3886

Re:返答:ファイル読み出し・編集・画面出力
投稿者---REE(2005/06/03 09:41:02)


元のファイルを編集する必要があるのですか?
最初の問題をみたときは、単に編集結果を表示するだけでよいように感じましたが?

1行読むたびにstrtokで分離したものを各項目用の変数に一度格納して、
printfで一度に表示すると楽になりそうです。



この投稿にコメントする

削除パスワード

No.3890

Re:返答:
投稿者---シグイン(2005/06/03 10:35:22)


>元のファイルを編集する必要があるのですか?
>最初の問題をみたときは、単に編集結果を表示するだけでよいように感じましたが?
 ここでは性別を1・2からman・womanなんかにかえて出力したいため編集が必要です。

>1行読むたびにstrtokで分離したものを各項目用の変数に一度格納して、
>printfで一度に表示すると楽になりそうです。
 それぞれ変数に格納ですか、strtokで分離したものってそれぞれ変数に格納できるのですか? 具体的にどんな感じかサンプルを見せていただいてもよろしいでしょうか?



この投稿にコメントする

削除パスワード

No.3891

Re:返答:
投稿者---REE(2005/06/03 11:34:55)


>>元のファイルを編集する必要があるのですか?
>>最初の問題をみたときは、単に編集結果を表示するだけでよいように感じましたが?
> ここでは性別を1・2からman・womanなんかにかえて出力したいため編集が必要です。

編集が必要なのはわかりますが、元のファイルに編集結果を書き戻す必要はありませんよね?という確認です。

>>1行読むたびにstrtokで分離したものを各項目用の変数に一度格納して、
>>printfで一度に表示すると楽になりそうです。
> それぞれ変数に格納ですか、strtokで分離したものってそれぞれ変数に格納できるのですか? 具体的にどんな感じかサンプルを見せていただいてもよろしいでしょうか?

簡単すぎるサンプルです。

char *p1,*p2,*p3;
p1 = strtok(ss,",");
p2 = strtok(NULL,",");
p3 = strtok(NULL,",");

printf("%s:%s:%s",p1, p2, p3);



この投稿にコメントする

削除パスワード

No.3893

Re:返答
投稿者---シグウィン(2005/06/03 20:19:48)


>>元のファイルを編集する必要があるのですか?
>>最初の問題をみたときは、単に編集結果を表示するだけでよいように感じましたが?
> ここでは性別を1・2からman・womanなんかにかえて出力したいため編集が必要です。

>編集が必要なのはわかりますが、元のファイルに編集結果を書き戻す必要はありませんよね?という確認です。
 書き戻す必要はないですね。


この投稿にコメントする

削除パスワード

No.3894

Re:返答
投稿者---まきじ(2005/06/03 20:45:43)


>書き戻す必要はないですね。

3880 で納得してるので、ファイルの内容を変更するものだと思ってました。
標準出力に出力するのを、woman あるいは man にしたかったのですね。
それでしたら、if 文で簡単にできると思いますが?


この投稿にコメントする

削除パスワード

No.3895

まきじさんへ
投稿者---シグウィン(2005/06/03 21:57:03)


>>書き戻す必要はないですね。
>
>3880 で納得してるので、ファイルの内容を変更するものだと思ってました。
>標準出力に出力するのを、woman あるいは man にしたかったのですね。
>それでしたら、if 文で簡単にできると思いますが?

大変申し訳ないです。
確かにそのときは納得していたのですが、先程率直につっこまれた時本当にそうだと思ったから正直に答えました。

 ちなみにこんな感じに作りました。
while( 1 ){
        /* ファイルから1行読み込む */
        get_eof = fgets(buf, LINE_MAX, fp);

        /* 読み込めなかったら終了 */
        if(get_eof == NULL){
            break;
        }

        /* 番号の切り出し */
        str = strtok(buf,",");
        strcpy(number, str);
        number_i = atoi(number);

        /* 名前の切り出し */
        str = strtok(NULL,",");
        strcpy(name, str);

        /* 性別の切り出し */
        str = strtok(NULL,",");
        strcpy(gender, str);
        gender_i = atoi(gender);
        /* 性別を「man」か「woman」に変換 */
        if(gender_i == 1){
            strcpy(gender_str, "man");
        }
        else{
            strcpy(gender_str, "woman");
        }






/* 生徒1人分のデータを画面に出力 */
        printf("|%-10d|%-30s|%-6s|%-4d|%-4d|\n", number_i, name, gender_str, nen_i, kurasu_i);
    }




この投稿にコメントする

削除パスワード

No.3896

Re:まきじさんへ
投稿者---elder(2005/06/03 22:26:29)


入力データのフォーマットが決まっているのであれば、
sscanf(), fscanf()の方が簡単です。

>        /* 性別を「man」か「woman」に変換 */
>        if(gender_i == 1){
>            strcpy(gender_str, "man");
>        }
>        else{
>            strcpy(gender_str, "woman");
>        }

それから、私はこのような場合、よく配列を使います。
これが良いやり方というわけではありませんが…。

char *gender_str[] = {"man", "woman"};

while (fscanf(fp, "%d,%[^,],%d,%d,%d", &number_i, name, &gender_i, &nen_i, &kurasu_i) != -1) {
    printf("|%-10d|%-30s|%-6s|%-4d|%-4d|\n", number_i, name, gender_str[gender_i - 1], nen_i, kurasu_i);
}




この投稿にコメントする

削除パスワード

No.3899

elderさんへ
投稿者---シグウィン(2005/06/04 01:21:32)


>入力データのフォーマットが決まっているのであれば、
sscanf(), fscanf()の方が簡単です。
ただこのデータを整列したり、いろいろ計算したりするとそうでもない気がします。これからやろうとしています。

基本的な質問ですがfscanfで入力している名前の書式%[^,]は、空白を含んだ名前(例:nakata naoki)も正しく処理してくれるっていう意味ですよね。




この投稿にコメントする

削除パスワード

No.3901

Re:elderさんへ
投稿者---elder(2005/06/04 12:30:39)


>ただこのデータを整列したり、いろいろ計算したりするとそうでもない気がします。これからやろうとしています。

データを取り出す分にはstrtok()と変わらない気がするのですが…。

計算がどのような計算かはわかりませんが、
データを整列されるのであれば、構造体を使うと良いです。


>基本的な質問ですがfscanfで入力している名前の書式%[^,]は、空白を含んだ名前(例:nakata naoki)も正しく処理してくれるっていう意味ですよね。

実行してみるとわかると思います。
%[^,]は、「カンマ以外の文字をカンマが現れるまで読む」という動作をします。




この投稿にコメントする

削除パスワード

No.3902

再:elderさんへ
投稿者---シグウィン(2005/06/04 13:30:05)



>データを取り出す分にはstrtok()と変わらない気がするのですが…。
strtok()と何が変わらないんですか?

>>計算がどのような計算かはわかりませんが、
>データを整列されるのであれば、構造体を使うと良いです。
そうですね、構造体を使うといいと私も考えています。

>実行してみるとわかると思います。
>%[^,]は、「カンマ以外の文字をカンマが現れるまで読む」という動作をします。
実行してみました。もしカンマがなかったらこれは使えないってことになりますかね?




この投稿にコメントする

削除パスワード

No.3903

Re:再:elderさんへ
投稿者---まきじ(2005/06/04 13:37:39)


>strtok()と何が変わらないんですか?

区切り文字で区切るのは、strtok でも fscnaf でもできるって事でしょう。
フィールドの数が、固定値の場合は、fscanf が良いと思います。
非固定値なら、strtok が良いと思います。

>実行してみました。もしカンマがなかったらこれは使えないってことになりますかね?

それも、やってみればわかります。
シグウィンさんの望む動作にはならないと思います。


この投稿にコメントする

削除パスワード

No.3904

再質問
投稿者---シィグウィン(2005/06/04 17:00:49)


毎度親切にありがとうございます。

>非固定値なら、strtok が良いと思います。
固定値は今回みたいの場合ですが、非固定値とは具体的にどんな場合ですか?

>>実行してみました。もしカンマがなかったらこれは使えないってことになりますかね?
>それも、やってみればわかります。
カンマでなくで空白で区切りましたら1行目からエラーになりました!



この投稿にコメントする

削除パスワード

No.3905

単純に
投稿者------(2005/06/04 17:17:05)


>固定値は今回みたいの場合ですが、非固定値とは具体的にどんな場合ですか?

>>>実行してみました。もしカンマがなかったらこれは使えないってことになりますかね?
の場合のことでは?


この投稿にコメントする

削除パスワード

No.3906

Re:再質問
投稿者---まきじ(2005/06/04 18:10:29)


>固定値は今回みたいの場合ですが、非固定値とは具体的にどんな場合ですか?

1 行に入る情報が違う場合。

>カンマでなくで空白で区切りましたら1行目からエラーになりました!

区切り文字を、' ' をにすれば良いだけでは?
当然、データに空白があれば、それも区切り文字として扱われます。


この投稿にコメントする

削除パスワード

No.3907

ありがとうございました!
投稿者---シィグウィン(2005/06/04 18:39:15)


>1 行に入る情報が違う場合。
たとえば、クラスによって入れる情報がちょっと違う場合とかですか。

>区切り文字を、' ' をにすれば良いだけでは?
>当然、データに空白があれば、それも区切り文字として扱われます。
そうですね。 もう少し頭を柔らかくして考えたほうがいいですね。

まだこれから機能追加していく予定ですので、近いうちにまた質問しに来ます。
ですのでよろしくお願いします。
最後になりましたが、ありがとうございました。


この投稿にコメントする

削除パスワード

No.3892

Re:返答:
投稿者---επιστημη(2005/06/03 11:35:30)


> それぞれ変数に格納ですか、strtokで分離したものってそれぞれ変数に格納できるのですか? 具体的にどんな感じかサンプルを見せていただいてもよろしいでしょうか?

あなた、冒頭のコードで p = strtok(...) してますやん。



この投稿にコメントする

削除パスワード

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




掲示板提供:Real Integrity