- ベストアンサー
FILE型について
今、Cのプログラムでやろうとしているものがあります。 それはFILE型が指しているデータを直接書き換えるといったことをすれば簡単に出来そうなのですがやってもいいのでしょうか? 例:*(stdin->curp) = '\0' curpはバッファの現在地 私はFILE型の中身をまだ全て理解していないので、無理やりなやり方だとは思うのですが実際のところどうなのかわかりません。
- C・C++・C#
- 回答数7
- ありがとう数7
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
> それはFILE型が指しているデータを直接書き換えるといったことをすれば簡単に出来そうなのですがやってもいいのでしょうか? 私はよくやりますが、それは自分が標準ライブラリを実装している場合です。標準ライブラリの実装者の立場からすれば、ユーザーにFILE型の中身はできれば見せたくありません。 本来、できるのであれば、FILE型というのはその定義の詳細をユーザーに見えなくすべきものです。ところが実際にはユーザーに見えるような実装にせざるを得ないのはいくつかの理由があります。 ひとつは、feofなどをマクロやインライン関数で実装するには、FILE型の詳細がヘッダ内で可視でなければならないからです。もう一つは、規格上、FILE型はオブジェクト型でなければならないので、void型や不完全型にできないからです。
その他の回答 (6)
- jacta
- ベストアンサー率26% (845/3158)
> No.5のお礼に書いたソースなんですがアドレスの引き算などはしてもいいことなんでしょうか? ライブラリの実装者以外はやってはいけないことです。 FILE型はオブジェクト型だということが決まっているだけですので、構造体だとは限りません。例えばint型でも構わないわけです。また、構造体だとしても、どんなフィールドがあるかは実装依存です。 もし、どうしてもバッファの中を覗きたいのであれば、setbufかsetvbufで、自分で用意した配列をバッファにするように設定してください。
- sha-girl
- ベストアンサー率52% (430/816)
FILE型を書き換えてどうなるかは処理系に依ります。 例えばWindowsの場合FILE fp;でfpの中身をどういじろうが、 なにもおきません。 その後実行しても不正なポインタをさしてるだけで 例外が発生するだけです。 fopenや_openの実体はWindowsAPIのCreateFileなのです。 つまりたんなるハンドル(ハンドルとはOSから発行される整理券のような数字)にすぎません。 ちなみにVisualC++ならopen.cというソースをみればわかります。
お礼
とりあえず急ぎで作ったので中途半端ですが・・・、こういった使い方はどうでしょう? 予定:String型に近いものを作る。 #include<stdio.h> #include<stdlib.h> #include<string.h> char *String(void); int main(void) { char *str; str = String(); printf("%sを入力\n",str); free(str); return 0; } char *String(void) { char *head = stdin->curp; char c; char *p; while((c = fgetc(stdin)) != EOF && c != '\n'); if(ferror(stdin)) return NULL; p = malloc(stdin->curp - head + 1); //入力した文字数 + '\0'個の領域確保 memcpy(p,head,stdin->curp - head); //文字を写す p[stdin->curp - head] = '\0'; return p; } 変な所などがあったらじゃんじゃん言って下さい。 作る意味ないじゃんとか言ってくれてもいいです。
- toysmith
- ベストアンサー率37% (570/1525)
目的によりますね。 「ここをこうしたら、どうなるんだろう?」っていう実験的、研究的な目的なら推奨します。 しかし、実用的な目的なら止めておいたほうがいいでしょう。 知的欲求を満たすためなら何をしたっていいと思いますよ。 自己責任の範疇でなら。
お礼
みなさんの言うとおり、中身はいじらないようにします。 とりあえず別の方法を思いついたのでそれで行ってみようかと思います。
- ballville
- ベストアンサー率47% (233/487)
>FILE型の中身をまだ全て理解していない 理解しなくてよいように、FILE型というものが存在するのです。 ->curp という書き方からすると、ボーランド系のコンパイラをお使いのようですが、ほかのコンパイラ(MSーCやLSIーCなど)のFILE型にはcurpというメンバはありません。 FILE型をどのように実現するかはそれぞれのコンパイラベンダーに完全に任されています。つまり、コンパイラベンダーはいつでも、FILE型の中身を変えることもできるのです。 もちろん、FILE型がどのようにできているのか興味を持ってstdio.hなどを調べることは勉強になりますが、そこで得た知識を実際に直接応用することはできません。 http://www.geocities.co.jp/SiliconValley-Bay/7437/c/file.htm
お礼
私も3日ぐらい前までそのことに気付いていませんでした。 本に書いている内容を実行しようとしたら動かなかったので、stdio.hの中身を見てそのことを初めて知りました。
- ultraCS
- ベストアンサー率44% (3956/8947)
何がやりたいかわかりませんが、途中で退避しておいて前に戻るとか、実際には固定長のファイルで、直接編成のように扱いたいといった用途ならともかく、中をいじるのはあまりお勧めできませんね。 まあ、ファイルが壊れても良いという前提いろいろやってみるのは良いと思いますが、思わぬ副作用でシステムまでいってしまうことも考えられるので、独立した環境を容易し、経験を積みましょう。 低レベルアクセス関数を使えば済みそうなんだけど
お礼
すいません、返事が遅れました! 中身を書き換えるのがいけないのなら参照した結果を元にデータを読み取ることはしてもいいのでしょうか? あれから色々考えていたのですが、まだ作っていないので内容ははっきり言えないのですが・・・
- phoenix343
- ベストアンサー率15% (296/1946)
???何をしたいの??? 基本的にFILE型の中身はいじらないほうがいいよ。 何のために標準関数があるの? fopen、fclose、fseek、fprintf、…
お礼
思っていたとおり、やっぱしいじらないほうがいいですか。
関連するQ&A
- C言語 ドラッグとファイル名の表示
はじめまして。 C言語を学習しています。 PCのOSはWindows XPです。 ドラッグしたファイルのファイル名を表示する方法として参考書に例文が載っていますが、以下の部分が理解できません。 1、参考書に、「【fflush(stdin);】という記述は、出力バッファを強制出力する関数である fflush で、入力バッファである stdin をクリアしています。」との説明があります。 出力バッファの意味と入力バッファであるstdinについての説明が参考書に無く、ネットで調べましたが理解できる記事がありませんでした。 出力バッファの意味と入力バッファであるstdinの意味を教えてください。 2、【getchar();】は、実行されるとキーボードからの入力を待ち、エンターキーが押されると入力待ちを終了、入力したうちの1文字目を返り値として返す関数とのことですが、下記のプログラムでどのような役割をしているのか教えてください(下記のプログラムになぜgetchar関数が必要なのかがわかりません)。 なにとぞ、よろしくお願い致します。 ●参考書の例文 次のプログラムは、プログラム実行画面(コマンドプロンプトのような黒い画面)にデスクトップ等のファイルをドラッグし、そのファイル名を表示する例です。 #include <stdio.h> int main(int argc,char *argv[]) { if (argc > 1) { printf("%s\n",argv[1]); } fflush(stdin); getchar(); return 0; }
- ベストアンサー
- C・C++・C#
- CSVファイルの処理方法
PerlでCSVファイルの処理をしようとしています。 CSVファイル(ここではdata1.csvとします)の中身は、A列とB列に数値が1000行程表記されています。 -5,1 -4,2 -3,3 ・ ・ ・ 作成したPerlのファイル(ここではtest1.plとします)下のようにし、 while ($_=<stdin>){ print"$_\n"; } Cygwinコマンド上で、 $ perl test1.pl <data1.csv と入力すると、CSVファイル(data1.csv)の数値がCygwinコマンド上に全て表記されます。 前置きが長かったのですが、CSVファイル(data1.csv)の3行目までの数値だけをCygwinコマンド上に表記したい場合、どのようにプログラムすればよいのですか。 お願いします。
- ベストアンサー
- Perl
- fflush()、setbuf()について
C言語にお詳しい方、ご回答お願いします。 fflush関数は、「バッファに格納されているデータを吐き出す。」とあるのですが、具体的にどのような動作をするのでしょうか? (1)fflush(stdin),fflush(stdout)とそれぞれ記述するとどのような動作をするのか。 (2)データをフラッシュしたいときとは、具体的にどんなときか。(scanfなどで続けてデータの入力を行うこと以外に) setbuf関数は、「出力バッファをユーザバッファに指定」とあるのですが、具体的にどういう意味なのでしょうか? (1)setbuf(stdout,buf)、setbuf(stdin,buf)とそれぞれ記述するとどのような動作をするのか。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- VC++2005 ファイル読み込み
現在VC++2005でプログラムをしています。 そこで質問があるのでよろしくお願いします。 PCに保存してあるテキストファイルをプログラムで読み込み、その中のテキストからいろいろな判断をするというようなプログラムを作りたいと考えています。 そこでファイルのオープンなでは理解できたのですが、ファイルの中のテキストを読み判断するという方法がよくわからず質問しました。 また、テキストファイルの中身は数字と文字列になっています。 下にその例を書きます。 7,000 ディスプレイ 5,000 ゲーム などです。 そこで6,000以上なら高いというような判断を行いラベルに表示するというような形です。 説明が下手かもしれませんがよろしくお願いします。
- 締切済み
- C・C++・C#
- fgetsなどのときのstdinのバッファを消すには?
こんにちは,今C(C++でない)を使用しています。 たとえば, char str[20] fgets(str,sizeof(str),stdin) としたときに20字以上を打つと,stdinのバッファに20字以上の分が残ったままになります。 C++などでは fflush(stdin)で,うまくいきますが,普通のCでは対応がされていないみたいでうまくいきません。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- 入力されたとき,何も入力しない,もしくは20字以上だと再入力のプログラム??
こんにちわ, 今Cの勉強をしているんですが,入力をして,何も入力しないもしくは20字以上だと再入力させるのプログラムを作りたいんですけどどうしたらよろしいでしょうか。 char sk[21]; start1: while(stdin = " puts("入力"); if ((*fgets(sk,sizeof(sk),stdin) < 0x21) || strlen(sk) >= 21 ) { puts("error"); goto start1; } だと,20字以上のときにstdinのバッファに残ってしまってエラー表示が2度出ます。 ちなみにfflush(stdin)は使用できないANSI C規格です。 よろしくお願いします。
- 締切済み
- C・C++・C#
- ファイルにロック
Cで自分で作ったtest.exeという 名前のプログラムがありまして (どんなプログラムかは事情が あってここに書くことは 出来ないのですが…) 起動するとdata.txtとin.txtの 読み込みをしてから処理を するように作ったのですが この時読み込むdata.txtと in.txtを自作したtest.exe以外で 開いても中身がわからない (暗号化etc…)もしくは開けない ようにする方法はありますか? data.txtの中身は全て日本語で in.txtの中身は全て半角英語です どちらも7000行ほど あります 回答よろしくおねがいします
- 締切済み
- その他(インターネット・Webサービス)
- ファイルの作成方法…
VBでテキストファイルの中身を開くプログラムを作成しました。 そのテキストファイルの中身を変更(編集)し、それを同じファイルに上書き保存するのではなく、開いたファイルのある同じフォルダ内に新しいファイルを作り保存したいと思っています。 <例>test1.txtというファイルを開き中身を編集してそれを同じフォルダ内に新しくtest2.txtというファイルを作って保存するといった感じです。 そこで新しいファイル名で保存する(新しいファイルを作成する)方法を教えて欲しいんです、こんな説明で分かってもらえるか不安ですが…、どなたか分かる方教えていただけませんでしょうか? かなりの初心者なのですが、私でも理解できるようなプログラムだと嬉しいです。 よろしくお願いします。
- ベストアンサー
- Visual Basic
- avastで一部のフォルダ、ファイル等を検査しないためには・・・
avastで一部のフォルダ、ファイル等を検査しないためには、どうしたらいいんでしょうか? やり方は分かるのですが、どう指定したらいいのかがわかりません。 例として、C:\Program Files\test\ad\という所があったとして そのadの中身をすべて検査しないように一気に例外したいのですが。 一つずつではなくて、一気に一つにまとめる方法です。 後、それらを検査しないようにするとフォルダの中身のフォルダも検査されないようになるんですか? ご回答よろしくお願いします。
- 締切済み
- ウィルス・マルウェア
お礼
お返事ありがとうございます。 書いていることはそのとおりだと私も思います。 最後の3行がまだ理解出来ていませんが、頑張って自分で内容の意味を考えてみます。
補足
No.5のお礼に書いたソースなんですがアドレスの引き算などはしてもいいことなんでしょうか? 使い方は間違っていないでしょうか?