🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

Q&A

解決済

2回答

1643閲覧

fwrite関数の第1引数にint型の変数を指定しても、数値が出力されない。

Eisaku_Yoshida

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

0グッド

0クリップ

投稿2021/01/15 13:27

いつもお世話になっております。

テキストファイルの内容を10進数の数値で表示させたいと考えております。
①(terminal上に記載)で、ファイルから読み取った文字を数値に変換し、
その数値が入った変数をfwrite関数で標準出力に出力しているつもりです。
ですが、今出力されるのは、元々そのファイルに記載されている文字情報だけです。(②)
どうしてこうなってしまうのか分かりません。

ご教授いただけませんでしょうか。
よろしくお願いいたします。

C

1 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5 6 7#define ARGUMENT_MUM 2 8#define SIZE 254 9#define TRUE 1 10 11int main(int argc, char** argv) 12{ 13 FILE *fp = NULL; 14 char fromFile[SIZE] = {0}; 15 char fileContents[SIZE] = {0}; 16 int iFileContent = 0; 17 int iRet = 0; 18 19 20 if (argc != ARGUMENT_MUM){ 21 printf("コマンドライン引数エラー\n"); 22 return -1; 23 } 24 strncpy(fromFile, argv[1], sizeof(fromFile)); 25 fp = fopen(fromFile, "rb"); 26 if (fp == NULL){ 27 printf("fopen失敗\n"); 28 return -1; 29 } 30 31 while(TRUE){ 32 iFileContent = 0; 33 // ファイルの読み込み 34 iRet = fread(fileContents, sizeof(char), 1, fp ); // 1バイトずつ読んでいって、 35 if (iRet < 1){ // 読み取れなくなったら 36 if (feof(fp)){ // ファイルの終端の場合 37 break; 38 }else{ // それ以外 39 printf("fread読み込み失敗\n"); 40 break; 41 } 42 } 43 // 標準出力への出力 44 iFileContent = (unsigned char) fileContents[0]; // 文字を対応する数値に変換 // その数値を標準出力に出力 45 iRet = fwrite(&iFileContent, sizeof(iFileContent), 1, stdout); 46 if (iRet < 1){ // 書き込めなかったら 47 printf("fwrite書き込み失敗\n"); 48 break; 49 } 50 } 51 52 iRet = fclose(fp); 53 if (iRet != 0){ 54 printf("fcloseエラー"); 55 return -1; 56 } 57 58 return 0; 59}

gdb

1Thread 2 hit Breakpoint 1, main (argc=2, argv=0x7ffeefbff6d8) at 問題10.c:28 228 iRet = fread(fileContents, sizeof(char), 1, fp ); // 1バイトずつ読んでいって、 3(gdb) n 429 if (iRet < 1){ // 読み取れなくなったら 5(gdb) p fileContents 6$1 = "a", '\000' <repeats 252 times> 7(gdb) n 8 9Thread 2 hit Breakpoint 2, main (argc=2, argv=0x7ffeefbff6d8) at 問題10.c:38 1038 iFileContent = (unsigned char) fileContents[0]; // 文字を対応する数値に変換 11(gdb) n 12 13Thread 2 hit Breakpoint 3, main (argc=2, argv=0x7ffeefbff6d8) at 問題10.c:40 1440 iRet = fwrite(&iFileContent, sizeof(iFileContent), 1, stdout); 15(gdb) p iFileContent 16$2 = 97 // (①)★ちゃんとiFileContentの中身には、97が入っている! fwriteでiFileContentの内容を出力するようにしているので、97が標準出力に出力されて欲しい!★ 17(gdb) n 1841 if (iRet < 1){ // 書き込めなかったら 19(gdb) p iRet 20$3 = 1 21(gdb) n 2225 while(TRUE){ 23(gdb)

terminal

1ユーザー名@コンピュータ名 修正後 % ./a.out test.txt (②) 2aaa 3bbb 4ccc 5ddd 6ユーザー名@コンピュータ名 修正後 %

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

int値をそのまま書いているので、そのまま表示しても駄目です。

sh

1./a.out test.txt | hexdump -C

のように、16進ダンプにする等して確認しましょう。

ただ、目的が

10進数の数値で表示させたい

なのであれば、そのまま書くのでなく、10進数に変換する必要があります。

C

1 iFileContent = (unsigned char) fileContents[0]; // 文字を対応する数値に変換 // その数値を標準出力に出力 2 iRet = printf("%d ", iFileContent); 3 if (iRet < 0){ // 書き込めなかったら 4 printf("printf書き込み失敗\n"); 5 break; 6 }

ですね。

投稿2021/01/15 13:55

otn

総合スコア85893

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Eisaku_Yoshida

2021/01/18 01:03 編集

otn様、いつもご回答ありがとうございます! fwrite関数の第一引数がvoidへのポインタだったので、 int型へのポインタを指定しても、そのままint型の値が表示されるのでは無いかと思っていました。 例えば、fgets関数の第一引数は、char型へのポインタだと決まっているので、例え、第一引数に、数値を指定したとしても、アスキーコードで、対応する文字が表示されるというのは、理解できます。 fwrite関数自体のソースコードを見てみたのですが、 void*型の第一引数でしてされた仮引数が、ソースコード内で、char *にキャストされているのが、分かりましたので、おそらくその結果、結局は、内部では、char *として扱われているのでは無いかなと思いました。 (https://chromium.googlesource.com/chromiumos/third_party/glibc/+/cvs/libc-970720/stdio/fwrite.cの32行目) だから、数値を引数として、fwrite関数に渡しても、その数値に対応するアスキーコードの文字で表されているのでは無いかという仮説を立てました。 この考えは、適切でしょうか。
otn

2021/01/18 03:27

> その数値に対応するアスキーコードの文字 これは65という数値が「A」になると言うことを言ってますか? そうだとすると一部合っています。 intの65だと(intが4バイトとして)、メモリ上では(エンディアンをさておくと)、16進で 00 00 00 41、2進で 00000000 00000000 00000000 0100 0001 ですが、これを、 ・ int の 65 と見る ・ 文字列の「NUL NUL NUL A 」と見る のどちらを採用するか(あるいはそれ以外)は見る人の主観です。 fwriteは見る人の主観などは関係なく、メモリ上のデータをそのままファイルに書きます。
Eisaku_Yoshida

2021/03/19 06:48

返信が遅くなり、申し訳ございませんでした。。 ご回答ありがとうございました!
guest

0

文字列を読み出したいなら、文字列を書き込みましょう

しごくあたりまえのおはなしです

投稿2021/01/15 13:31

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Eisaku_Yoshida

2021/03/19 06:49

ご返信が遅くなり申し訳ございませんでした。。 はい。 ご回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問