71839


上手くreadできません。

text.txt

[code]

    ABC
    
[/code]

main.c

[code]

    #include <unistd.h> 
    #include <stdio.h>
    #include <fcntl.h>
    #include <stdlib.h>
    
    int main()
    {
        int sz, fd = open("text.txt", O_RDONLY | O_CREAT);
        char *c = (char *)calloc(100 , sizeof(char));
        
        printf("%d\n", fd);
        sz = read(fd, c, 100);
        printf("called read(% d, c, sz).  returned that"
             " %d bytes  were read.\n", fd, sz);
        printf("%s", c);
        return 0 ;
    }
    
[/code]

これの出力が以下です

[code]

    3
    called read( 3, c, sz).  returned that 12 bytes  were read.
     ■A
    
[/code]

まず、ABC しか書かれてないのに 12byte 読んでるのは変だし、"ABC" と表示されないのもおかしいです。

これは Windows を使っているせいでしょうか？なお、コンパイラは mingw です。  
Linux で実行した場合は正常に動作しました。


CC BY-SA 4.0
2020-11-10T04:41:09.453
71835
2020-11-10T10:00:01.437
2020-11-10T08:26:27.940
3060
36091
question
c
readがうまくできない。


Windows上の`text.txt`ファイルが、BOMおよび改行コード付きのUTF-16LEエンコーディングであれば、それは正しい動作です。

該当ファイルをマウス右クリック等でプロパティを確認すれば、サイズが12バイトになっているでしょう。

そのファイルを16進数でダンプ表示すると、以下のようになるはずです。

[code]

    FF,FE,41,00,42,00,43,00,0D,00,0A,00,
    
[/code]

Windows上のC言語での`char`は8bitで、printfの%sは0x00で終端されるcharの配列であるモードで使われていたのでしょう。  
ファイル読み取りのサイズはバイト単位で通知されます。

そのため、読み取ったサイズは12バイトだし、`printf("%s", c);`では`FF,FE,41`までが出力対象で、`
■A`のように表示されます。(ちなみにVC++のコンソールアプリで(動くように修正して)やってみたら、`A`と表示された(Aの前は実際には中点`・`のように見えました)ので`FF,FE`の表示に関しては環境依存の可能性が大きいかもしれません)

* * *

Linux上で上手くいったのは、Linux上で使用した`text.txt`ファイルがWindows上の物とは違っていた(ASCII/ShiftJIS/UTF-8BOM無しで、改行コード無し)のだと思われます。


CC BY-SA 4.0
2020-11-10T05:34:24.890
71839
2020-11-10T10:00:01.437
2020-11-10T10:00:01.437
26370
26370
71835
answer


原因はおそらく @kunif さんの回答であっていそうですが、提示プログラムはいくつか問題を抱えていますので指摘だけ

<https://linuxjm.osdn.jp/html/LDP_man-pages/man2/open.2.html>

  1. `open()` に `O_CREAT` を指定する場合は第３引数として `mode` を指定しなければなりません。
  2. `open()` で `O_RDONLY` と `O_CREAT` を同時に指定するのはたぶん誤りです。こうすると

  * 指定ファイルが既に存在するとき `O_CREAT` は無視される（こっちはおそらく期待通り）
  * 指定ファイルが無いとき `O_CREAT` により 0 バイト長の新規ファイルが作られる（こっちは多分期待通りでない）  
0 バイト長なので直ちに EOF となる

  * 作られた新規ファイルの権限が不定値 (1. により)

* * *

[cygwin](/questions/tagged/cygwin "'cygwin' のタグが付いた質問を表示") /
[mingw](/questions/tagged/mingw "'mingw' のタグが付いた質問を表示")
の場合、ファイル内容のダンププログラムが付属しているので、これでバイト内容を確認するとよいでしょう。

[code]

    $ od -tx1 text.txt
    0000000 ff fe 41 00 42 00 43 00 0d 00 0a 00
    0000014
    $
    
[/code]

であれば BOM あり UTF-16LE 改行ありですし

[code]

    $ od -tx1 text.txt
    0000000 41 42 43
    0000003
    $
    
[/code]

であれば ASCII (UTF-8) 改行なしです。


CC BY-SA 4.0
2020-11-10T07:35:52.430
71840
2020-11-10T07:35:52.430
8589
71835
answer