ファイルの読み書き

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ひよこん

ファイルの読み書き

#1

投稿記事 by ひよこん » 15年前

初歩的な質問で大変申し訳ありません
ファイルをfgetsで読み込んだものをfprintfで書き込む方法を教えてください。

FILE *fp;
FILE *text
char str[100];
char *tt= "10";
char *search;

while(fgets(str,sizeof(str),fp))
{
if(tt != NULL)
{
search = strstr(str,tt);
fprintf(text, "%s", search);
}
}

セグメンテーション違反とのエラーになっているのですが、どのように解決すればいいのでしょうか?

シエル

Re:ファイルの読み書き

#2

投稿記事 by シエル » 15年前

fopenした?ほかにもたくさん変なとこあるけど。

ひよこん

Re:ファイルの読み書き

#3

投稿記事 by ひよこん » 15年前

変な所!? どこを直せばいいのでしょう!?

fopenはしました!

if(!(fp = fopen("sample.txt", "r"))){
printf("can not open file.\n");
}

while(fgets(str,sizeof(str),fp))
{
if(tt != NULL)
{
search = strstr(str,tt);
fprintf(text, "%s", search);
}
}
fclose(fp);
fclose(text);

上記のようにしています

バグ

Re:ファイルの読み書き

#4

投稿記事 by バグ » 15年前

読み込み用のファイルはオープンされているようですが、書き込み用ファイルはオープンされていないように見えます。

シエル

Re:ファイルの読み書き

#5

投稿記事 by シエル » 15年前

if(tt != NULL)
↑これは何か意味があるんですか?

ひよこん

Re:ファイルの読み書き

#6

投稿記事 by ひよこん » 15年前

>読み込み用のファイルはオープンされているようですが、書き込み用ファイルはオープンされていないように見えます。

書き込み用ファイルを追記してみました!
エラーはそのままです。


>if(tt != NULL)
↑これは何か意味があるんですか?

search = strstr(str,tt);
if(tt != NULL)

strstrの検索値で使用しようとしていました。

以下に変更してみましたがセグメンテーション違反がでてしまってしまいました

if(!(fp = fopen("sample.txt", "r"))){
printf("can not open file.\n");
}
if(!(text = fopen("test.txt", "w"))){
printf("can not open file.\n");
}

while(fgets(str,sizeof(str),fp))
{
search = strstr(str,tt);
if(tt != NULL)
{
fprintf(text, "%s", search);
}
}
fclose(fp);
fclose(text);

シエル

Re:ファイルの読み書き

#7

投稿記事 by シエル » 15年前

いえ、ttの値は変化しないのに、なぜif文で判定しているのかと思いまして。。

Mist

Re:ファイルの読み書き

#8

投稿記事 by Mist » 15年前

if(tt != NULL)



if(search != NULL)

の間違いじゃないですか?
ttがNULLになることは無いですよ。

toyo

Re:ファイルの読み書き

#9

投稿記事 by toyo » 15年前

fopenに失敗してるんじゃないでしょうか
sample.txtのパスが違うとか

ひよこん

Re:ファイルの読み書き

#10

投稿記事 by ひよこん » 15年前

>fopenに失敗してるんじゃないでしょうか
>sample.txtのパスが違うとか

if(search != NULL || search_20 != NULL)
{
printf("%s", search);
fprintf(text, "%s", search);
  }
printfすると、出力されるのでfopenは成功してると思っていたんですが、できていないのもあるんですか!?
調べてみます
fprintfの使い方を見直します。


> if(search != NULL)
にしてみました。セグメンテーション違反はなくなったのですが

次にもう一つ検索条件を追加しなければいけないのを忘れていまして

char *search_20;
char *tt_20 = "20";

while(fgets(str,sizeof(str),fp))
{
search = strstr(str,tt);
search_20 = strstr(str,tt_20);

if(search != NULL || search_20 != NULL)
{
fprintf(text, "%s", search);
fprintf(text, "%s", search_20);
}
}
上記のようにしたらまた、セグメンテーション違反になってしまいました。

ぜらーちん

Re:ファイルの読み書き

#11

投稿記事 by ぜらーちん » 15年前

簡単に作ってみた(if~elseの分岐は逆がいいかもしれないけど!になってたからこういう風に)

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

#define BUF 256
#define WORD "10"

int main(){

FILE *fp = NULL;
FILE *text = NULL;
char str[BUF] = {'\0'};
char *tt= WORD;
char *search = NULL;

if(!(fp = fopen("sample.txt", "r"))){
printf("can not open file.\n");
}
else{ //検索ファイルが読み込めたら
if(!(text = fopen("test.txt", "w"))){
printf("can not open file.\n");
}
else{ //出力ファイルも読み込めたら
while(1)
{
if(fgets(str, BUF, fp) == NULL){
break;//最後になるまで取り出し
}

search = strstr(str, tt); //検索してみる
if(search != NULL){ //見つかった
fprintf(text, "%s", search);
}
}
}
}
if(fp != NULL){
fclose(fp); //開いてもいないのに閉じたら困るため
}
if(text != NULL){
fclose(text); //開いてもいないのに閉じたら困るため
}

return(0);
}


エラーが出てた場所はここ
if(tt != NULL)
{
fprintf(text, "%s", search);
}

なんかこの辺で出てたきがする
その辺は調べて(’’

後if文だけど、ttで判定しても意味ない気がする
searchにNULLかアドレスだっけ、が入るのだから
searchで見ないとダメな気がする

バグ

Re:ファイルの読み書き

#12

投稿記事 by バグ » 15年前

if(search != NULL || search_20 != NULL) 
   { 
        fprintf(text, "%s", search); 
        fprintf(text, "%s", search_20); 
   }
この判定文はまずいんじゃない?片方がNULLの場合でも書き込みしちゃうけど…?
っていうか、どうしたいの?

ひょっとして、どちらもNULLでない場合に両方書き込みたいの?

ひよこん

Re:ファイルの読み書き

#13

投稿記事 by ひよこん » 15年前

ぜらーちん様ありがとうございます。
サンプルを提示していただきまして、早速なおしてなんでできないのか探してみます

>ひょっとして、どちらもNULLでない場合に両方書き込みたいの?
そうなのです。どちらかでもあれば、ファイルに書き込むという処理を入れたいです。

ぜらーちん

Re:ファイルの読み書き

#14

投稿記事 by ぜらーちん » 15年前

条件式が複数ある場合()したほうがいいと思う
× if(search != NULL || search_20 != NULL)
○ if( (search != NULL) || (search_20 != NULL) )

後、みたことなかったので質問なのですが

while(fgets(str,sizeof(str),fp))

これでループ条件としてはきちんと成り立っているのでしょうか?

シエル

Re:ファイルの読み書き

#15

投稿記事 by シエル » 15年前

>そうなのです。どちらかでもあれば、ファイルに書き込むという処理を入れたいです。

ん?どっちかがNULLだった場合に今のままじゃNULLの方も書き込んでしまうと思いますが。

ぜらーちん

Re:ファイルの読み書き

#16

投稿記事 by ぜらーちん » 15年前

なんか違和感あったと思ったら
while(fgets(str,sizeof(str),fp))

条件式がなかったのか

NULLになるまで回したいなら
while(fgets(str, sizeof(str), fp) != NULL)
じゃないと、ダメなような

if(search != NULL || search_20 != NULL){
fprintf(text, "%s", search);
fprintf(text, "%s", search_20);
}

↑だと、探せてもいない方を書き込もうとしたり
両方探せてたら二回書き込むことになるんじゃない?

//search出来ていた場合
if(search != NULL){
fprintf(text, "%s", search);
}
//search_20出来ていた場合
else if(search_20 != NULL){
fprintf(text, "%s", search_20);
}

で、いいのではないでしょうか?
二回デテキタラ…
else{
if(xxxx){}
}
で・・・

ひよこん

Re:ファイルの読み書き

#17

投稿記事 by ひよこん » 15年前

>while(fgets(str,sizeof(str),fp))
これでループ条件としてはきちんと成り立っているのでしょうか?

ファイルの中身を最初から最後まで表示されてましたのでいいのかと・・・

>ん?どっちかがNULLだった場合に今のままじゃNULLの方も書き込んでしまうと思いますが。

そうなんです!ファイルに書き込み処理がうまくいってないのであれなんですが
printfなどで表示されるとNULLなのに表示されてしまうんです。
でも、どうしたらでなくなるのかわからないんです。

バグ

Re:ファイルの読み書き

#18

投稿記事 by バグ » 15年前

>>ひよこんさん
>>そうなのです。どちらかでもあれば、ファイルに書き込むという処理を入れたいです。

結局どっちなの?(^_^;)
「どちらかでもあれば、ファイルに書き込む」というのは、「NULLではない有効なデータのみを書き込む」という事ですか?


>>ぜらーちんさん
>>条件式が複数ある場合()したほうがいいと思う
>>× if(search != NULL || search_20 != NULL)
>>○ if( (search != NULL) || (search_20 != NULL) )

自分の意図したように動いているならば、これは問題ないと思いますよ?
個人的には今回程度の判定文ならば、上記の方が好きですね。

更に条件が増えてきた場合は縦に並べますが…
if (search    != NULL ||
    search_1  != NULL ||
    search_2  != NULL ||
    search_3  != NULL ||
    search_4  != NULL ||
    search_20 != NULL)
{
    /* なんらかの処理 */
}
こんな感じ?

ひよこん

Re:ファイルの読み書き

#19

投稿記事 by ひよこん » 15年前

>「NULLではない有効なデータのみを書き込む」という事ですか?
そのようにしたいです

strstr()で探して、検索対象文字が見つかったらファイルに保存!
したいのはこれだけなんですが、うまくいかなくて(;;)

シエル

Re:ファイルの読み書き

#20

投稿記事 by シエル » 15年前

検索文字が見つかったら、その行だけファイルに保存したいってことですか?

バグ

Re:ファイルの読み書き

#21

投稿記事 by バグ » 15年前

おっとすれ違いでしたね。
if (search != NULL)
{
    fprintf(text, "%s", search);
}

if (search_20 != NULL)
{
    fprintf(text, "%s", search_20);
}
そういう事ならこれでどうでしょ?


>>ぜらーちんさん
>>なんか違和感あったと思ったら

>>while(fgets(str,sizeof(str),fp))

>>条件式がなかったのか

>>NULLになるまで回したいなら

>>while(fgets(str, sizeof(str), fp) != NULL)

>>じゃないと、ダメなような

駄目ではないです。
NULLが戻れば条件は必ず「偽」になって抜けるので、結果的にNULLではない値の間はループを続けられます。
勿論、明示的にすることによる読みやすさの向上というメリットはあります。

ひよこん

Re:ファイルの読み書き

#22

投稿記事 by ひよこん » 15年前

そうなのです。それでコレでできないかな?と思ったら動かなくて・・・

char *tt = 10
char *tt_20 = 20 

search = strstr(str,tt);
search_20 = strstr(str,tt);
 if((search != NULL ) || (search_20 != NULL ))
{
fprintf(text, "%s", search);
fprintf(text, "%s", search);
}

strstrで探して、
>検索文字が見つかったら、その行だけファイルに保存したい
そうしたいのです。

シエル

Re:ファイルの読み書き

#23

投稿記事 by シエル » 15年前

どちらの検索文字も見つかったら、その「行」を書き込むんだったら、

if(search!=NULL && search_20!=NULL)
{
fprintf(text,"%s",str);
}

どちらか一つでも、あれば書き込むんだったら

if (search != NULL || search_20!=NULL)
{
fprintf(text, "%s", str);
}



でいいのでは?

ぜらーちん

Re:ファイルの読み書き

#24

投稿記事 by ぜらーちん » 15年前

>>バグさん
ifとかの条件式の書き方とかって結局のところ好みですからね~
whileの部分なるほど、NULL省略してもok何ですね。メモメモ

>> if文だけだと、同じのが二回かかれてしまうような

>>ひよこんさん

例えば、例文として以下の文章があったとして…
in.txt
10 20 30 40 50 60
10 10 10 20
50
EOF

出力結果的にはどう出したいのでしょうか?
今のプログラムのままですと
out.txt
10 20 30 40 50 60
10 10 30 10 20

って出ます

それとも
out.txt
10 20
10 10 10 20

って感じに出したいのでしょうか?

ひよこん

Re:ファイルの読み書き

#25

投稿記事 by ひよこん » 15年前

例えば、例文として以下の文章があったとして…
in.txt
10 20 30 40 50 60
10 10 10 20
50
EOF

↓↓↓↓
out.txt
10 20 30 40 50 60
10 10 30 10 20

10があったからこの行書き込む
20があったからこの行書き込むです

バグ

Re:ファイルの読み書き

#26

投稿記事 by バグ » 15年前

>>検索文字が見つかったら、その行だけファイルに保存したい
>>そうしたいのです。

これで、やっとやりたい事が理解できた(^_^;)


>>ぜらーちんさん
>>if文だけだと、同じのが二回かかれてしまうような

確かにその通りですね。失礼いたしました…m(__)m


#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE        1024
#define LOAD_FILE_PATH    "load.txt"
#define SAVE_FILE_PATH    "save.txt"

int main(void)
{
    const char* pKey1 = "10";            // 比較用文字列その1
    const char* pKey2 = "20";            // 比較用文字列その2
    char szBuf[BUFFER_SIZE] = {0, };    // 1行分の文字列読み込み用バッファ
    FILE* pLoad = NULL;                    // 読み出し用ファイルポインタ
    FILE* pSave = NULL;                    // 書き込み用ファイルポインタ


    // 読み出し用のファイルオープン
    if ((pLoad = fopen(LOAD_FILE_PATH, "r")) == NULL)
    {
        // ファイルオープンに失敗
        printf("Load File Open Error\n");
        return -1;
    }

    // 書き込み用のファイルオープン
    if ((pSave = fopen(SAVE_FILE_PATH, "w")) == NULL)
    {
        // 読み出し用のファイルをクローズする
        if (pLoad != NULL)
        {
            fclose(pLoad);
        }

        // ファイルオープンに失敗
        printf("Save File Open Error\n");
        return -1;
    }

    // ファイルの終端まで1行ずつ読み込む
    while (fgets(szBuf, BUFFER_SIZE, pLoad) != NULL)
    {
        // 読み込んだ文字列にキー文字列が存在するか?
        if (strstr(szBuf, pKey1) != NULL || strstr(szBuf, pKey2) != NULL)
        {
            // 文字列が見つかったので書き込む
            fputs(szBuf, pSave);
        }
    }


    // ファイルをクローズして後始末をする
    fclose(pLoad);
    fclose(pSave);
    return 0;
}

ぜらーちん

Re:ファイルの読み書き

#27

投稿記事 by ぜらーちん » 15年前

なるほど、ちなみに例文修正(30抜けてた)

10 20 30 40 50 60
10 10 30 10 20

後は、10と20が二つあるから
10 20 30 40 50 60
10 20 30 40 50 60

っていう風にもしなくてok何ですよね?
10もしくは20もしくは10と20両方ある行を1行出すみたいな

それでしたら、上に出ているので大丈夫ではないでしょうか?

ひよこん

Re:ファイルの読み書き

#28

投稿記事 by ひよこん » 15年前

ありがとうございます! 動きました!
そして、すっごく勉強になりました。

お手数をお掛けし申し訳ありませんでしたが本当にありがとうございます

閉鎖

“C言語何でも質問掲示板” へ戻る