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


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

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

 詳しくはこちら



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

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


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

No.3634

途中の\r\nを見つけられない
投稿者---kaoru(2005/04/01 20:58:35)


度々申し訳ございません。

昨日投稿した、「どこでfree?」に関連したことなのですが、
どうぞよろしくお願い致します。

昨日のソースでは、元データ(検索されるデータ)を直接指定しました。
(char *p = "aaa\tbbb\tccc\tddd\r\n111\t222\t333\t444\r\n999";
のように。)
そして本日、この元データをファイルから読み込むようにしました。

ファイルの中身は、

123456789012 7777 9999999 888 N
123456789013 4444 6666666 555 N
123456789013 1111 3333333 222 N

のようなものです。
各項目の間はタブになっています。

改行コードは、0x0D・0x0A(CrLf)になっているにも関わらず、
また、Delimiterを、"\r\n"としているにも関わらず、
下記のReadUntilDelimiter関数のSizeが97となってしまいます。
(つまり、途中の行の改行を見つけてくれない。)
これは一体どういうことなのでしょうか?

また、free(Buf);の部分で落ちるのですが、
どうすればよいのでしょうか?
Bufのポインタを先に進めるのはいけないのですか?

----------------------

static int ReadUntilDelimiter (char *InBuf, char *Delimiter, char **OutBuf)
{
    char *p = NULL;
    int Size = 0;
    char *Buf = NULL;

    /* InBufから区切り文字を検索 */
    p = (char *)strstr(InBuf, Delimiter);

    /* 見つからない場合、終了 */
    if (p == NULL)
    {
        *OutBuf = NULL;
        return (0);
    }

    /* 見つかったら、区切り文字の手前までを返す */
    Size = p - InBuf;   /* ここの値が97になってしまう */
    Buf = (char *)malloc(Size+1);
    memset(Buf, 0x00, Size+1);
    memcpy(Buf, InBuf, Size);
    *OutBuf = Buf;

    return (Size);
}

int main(void)
{
    int FileSize = 99; /* とりあえず決め打ち */
    int FileNo;
    char    * Buf = NULL;
    char    * Buf_Row = NULL;
    int Size_Row = 0;
    short   ErrCD = 1;
    
    /* Bufを確保 */
    Buf = (char *)malloc(FileSize+1);
    memset(Buf, 0x00, FileSize+1);

    /* ファイルオープン */
    FileNo = open("C:\\SyukkaJ2.dat", O_RDONLY);

    /* ファイルサイズ分、Bufに読み込み */
    read(FileNo, Buf, FileSize);

    /* ファイルクローズ */
    close(FileNo);

    while(1)
    {
        /* 改行まで読み込み(読んだ後は、ポインタを次の行に進める) */
        Size_Row = ReadUntilDelimiter(Buf, "\r\n", &Buf_Row);
        Buf = Buf + Size_Row + 2;

        /* この後色々 */
        ・・・  {

        break;
    }

    /* メモリ開放 */
    free(Buf);  /* ここで落ちる */
    free(Buf_Row);

    return(ErrCD);
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:途中の\r\nを見つけられない 3635 ぽこ 2005/04/01 22:17:25
<子記事> Re:途中の\r\nを見つけられない 3636 Blue 2005/04/01 22:30:26
<子記事> Re:途中の\r\nを見つけられない 3642 nop 2005/04/04 11:13:53


No.3635

Re:途中の\r\nを見つけられない
投稿者---ぽこ(2005/04/01 22:17:25)


>改行コードは、0x0D・0x0A(CrLf)になっているにも関わらず、
>また、Delimiterを、"\r\n"としているにも関わらず、
>下記のReadUntilDelimiter関数のSizeが97となってしまいます。
>(つまり、途中の行の改行を見つけてくれない。)
>これは一体どういうことなのでしょうか?

VS.net2002の_read()の説明を抜粋します。
これが原因ではないでしょうか?

----ここから----
実際に読み取ったバイト数を返します。ファイル内に残っているバイト数が count より少ない場合や、ファイルがテキスト モードで開かれている場合は、このバイト数が count より少ないことがあります。テキスト モードでファイルを開くと、CR-LF (キャリッジ リターンとライン フィードの組み合わせ) が 1 個の改行文字に置き換えられます。そのため、戻り値にはラインフィード文字 1 個分しかカウントされません。
----ここまで----




この投稿にコメントする

削除パスワード

No.3636

Re:途中の\r\nを見つけられない
投稿者---Blue(2005/04/01 22:30:26)


>FileNo = open("C:\\SyukkaJ2.dat", O_RDONLY);
を
FileNo = open("C:\\SyukkaJ2.dat", O_RDONLY| _O_BINARY);
にすれば\r\nは見つかると思います。

それと
ReadUntilDelimiterはwhileのなかで何度も呼ばれる可能性があるのですよね。
そのたびにBuf_Rowをmallocするのに、freeするのは1度だけ。。

>Bufのポインタを先に進めるのはいけないのですか?
そのとおりです。

# 開発環境を書いてください。(OS、コンパイラなど)
# それと、ソースを載せる場合は#includ文からのせたほうがいいと思います。



この投稿にコメントする

削除パスワード

No.3637

Re:途中の\r\nを見つけられない
投稿者---kaoru(2005/04/02 00:13:56)


ぽこ様、Blue様、ありがとうございます。

まず、実際のコンパイラは SH-C ですが、
ハンディターミナル(以下HT)用のアプリなため、
SH-Cの標準関数でも使用できないものがあります。
また、このハンディターミナルでデバッグするのが大変なため、
とりあえずのテストコードは、VCでやっています。

VCでは、ぽこ様が教えてくださったように、実際のファイルサイズよりも
小さくなっていました。(\r\nが、\nのみとなっていました。)
HTでは、ファイルサイズは正しい(\r\nは2バイトでカウントされる)のですが、
Buf内の文字の文字コードを順に表示していくと、\rは、0x0Dと表示されず、
その後の文字コードも表示されませんでした。
(まるでBufの文字列が\rの前までしかないように表示される。)
ですが、\nはきちんと\nとして認識されているようですので、
改行は、\nで見るようにしました。
改行までの文字列を取得するのは、これで行けそうです。

※open時に、_O_BINARYを指定するのは、・・・できませんでした。
(HTの仕様?で、指定できるモードは、
O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_TRUNC、O_APPEND
のみでした。)

次に、

>Bufのポインタを先に進めるのはいけないのですか?
そのとおりです。

の件ですが、そうしますとどのようにすればよろしいでしょうか?
やりたいことは、\r\n前までのデータを1行ずつBuf_Rowに読み込み、
各Buf_Rowの全or一部分を他のデータと見比べたいのですが・・・。

> そのたびにBuf_Rowをmallocするのに、freeするのは1度だけ。。

そ、そうですね。気が付きませんでした。(汗)
loopの中に持っていきます。

> # 開発環境を書いてください。(OS、コンパイラなど)
> # それと、ソースを載せる場合は#includ文からのせたほうがいいと思います。

ご指摘ありがとうございます。以降気をつけます。m(_ _)m



この投稿にコメントする

削除パスワード

No.3638

Re:途中の\r\nを見つけられない
投稿者---Blue(2005/04/02 00:38:25)


>の件ですが、そうしますとどのようにすればよろしいでしょうか?
>やりたいことは、\r\n前までのデータを1行ずつBuf_Rowに読み込み、
>各Buf_Rowの全or一部分を他のデータと見比べたいのですが・・・。

mallocで取得した領域の先頭アドレスの値を保持する変数を追加し、
それに対してfreeすればよいかと。



この投稿にコメントする

削除パスワード

No.3640

Re:途中の\r\nを見つけられない
投稿者---kaoru(2005/04/04 02:02:34)


Blue様、何度もありがとうございます。

> mallocで取得した領域の先頭アドレスの値を保持する変数を追加し、
> それに対してfreeすればよいかと。

え?あ?
そ、それだけで良かったのですね。。。
やってみたところ、ちゃんとfreeできました。
何だかまだポインタについて分かっていないようです。
もう1回、ちゃんと勉強し直します。
どうもありがとうございました。



この投稿にコメントする

削除パスワード

No.3641

Re:途中の\r\nを見つけられない
投稿者---REE(2005/04/04 10:27:11)


>VCでは、ぽこ様が教えてくださったように、実際のファイルサイズよりも
>小さくなっていました。(\r\nが、\nのみとなっていました。)
>HTでは、ファイルサイズは正しい(\r\nは2バイトでカウントされる)のですが、

>※open時に、_O_BINARYを指定するのは、・・・できませんでした。
>(HTの仕様?で、指定できるモードは、
>O_RDONLY、O_WRONLY、O_RDWR、O_CREAT、O_TRUNC、O_APPEND
>のみでした。)

上記のことから、HTではバイナリモードで固定と推測されますので、
VCの時だけ、_O_BINARYを指定すればよいでしょう。
# もともとテキストモードはOSに依存するものです。


この投稿にコメントする

削除パスワード

No.3642

Re:途中の\r\nを見つけられない
投稿者---nop(2005/04/04 11:13:53)


>そして本日、この元データをファイルから読み込むようにしました。
>ファイルの中身は、
>
>123456789012 7777 9999999 888 N
>123456789013 4444 6666666 555 N
>123456789013 1111 3333333 222 N
>
>のようなものです。
>改行コードは、0x0D・0x0A(CrLf)になっているにも関わらず、
>また、Delimiterを、"\r\n"としているにも関わらず、
>下記のReadUntilDelimiter関数のSizeが97となってしまいます。
>(つまり、途中の行の改行を見つけてくれない。)
>これは一体どういうことなのでしょうか?

意味合いとしては、一行ずつ取り出したい、
という事でしょうか?
そういうことなら、fgets()で一行ずつ取り出すか、
全ファイル内容を読んだ後、strtok()でトークン分割、
と言う方法でも良いかと思いますが、どうでしょうか?


この投稿にコメントする

削除パスワード

No.3643

Re:途中の\r\nを見つけられない
投稿者---Blue(2005/04/04 11:24:18)


>そういうことなら、fgets()で一行ずつ取り出すか、
>全ファイル内容を読んだ後、strtok()でトークン分割、
>と言う方法でも良いかと思いますが、どうでしょうか?
私もその方法を考えましたが、

>まず、実際のコンパイラは SH-C ですが、
>ハンディターミナル(以下HT)用のアプリなため、
>SH-Cの標準関数でも使用できないものがあります。
ということなので、このうような方法になるのではないでしょうか?





この投稿にコメントする

削除パスワード

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




掲示板提供:Real Integrity