最も重要なことは、にある - 遅くなります。学ぶべきことがたくさんあり、一度に1つのステップを取らなければなりません。推測、コンパイル、変更があればそれを見て、何かを変えて(繰り返して)使うのは無理です。 それを見てください。あなたはstdin
/stdout
から/へとファイルへの基本的な入力/出力に興味がある、と述べた
はを書くために開かれました。 scanf_s
のウィンドウで作業しているのか、それとも以下のものが混在しているので、_s
のバージョンではないのかは不明です。それにもかかわらず、主要な違いが必要なパラメータになります。
はCでは、あなたは100
文字を保持するために、あなたのファイル名とのinputText を保持するための配列を宣言します。文字列を扱う場合、各文字列の末尾にヌル終端文字(末尾に'\0'
...またはちょうど0
、数値的に同じ)が必要です。 Cは、一般的に、すべて小文字の賛成で混在する場合、変数名を回避し、それはあなた次第です:それはあなたがfilename
またはinputtext
のいずれかで最大+1
文字99
のNUL終端文字(サイドノートを保存できることを意味します)あなたのfilename
やinputtext
の終わりを超えて書き込みを防止するために
、あなたはその制限あなたはどちらかで保存しようとした文字の数を確保する必要があります。 のフィールド幅はののオプションのフィールドには、のフィールドがあります。例えば、
scanf ("%99s", inputtext);
またはWindows用
_s
バージョン:しかし scanf_s ("%99s", inputtext, 100u);
、入力が読み込まれます%s
書式指定子として空白を含めることはできません"%99s"
の書式指定子を使用して最初の空白または改行まで。第2に、[Enter]を押した結果、ユーザ入力の最後に'\n'
が読み取られない(またはとにかく処理される)。これにより、次の入力が文字入力の場合に問題が発生します。scanf
は、次に読み取る文字として'\n'
を喜んで受け入れます。今すぐ%s
は空白文字('\n'
が空白である)をスキップしても問題ありませんが、scanf
という形式の文字列のような単純なものを作成する際に考慮する必要があります。
毎回入力ストリームにすべての文字のアカウンティングの習慣を得る。そうすれば、説明できないエラーであなたはガードされていません。
入力に空白を含めるには、scanf
の文字クラスの文字クラスを使用できます。たとえば、書式文字列として"%99[^\n]"
を使用できます。しかし、文字クラスでは先頭の空白は自動的に無視されませんが、の前にspace
のままにすることで柔軟性を提供できます。 " %99[^\n]"
。大事です。 fgets
またはPOSIX getline
は一般的に、ユーザ入力を処理するためのscanf
よりも好まれている理由(それもある。
今どのようにあなたは、space
を離れることに加えて?入力バッファ(ここでは例えばstdin
)に残され'\n'
を処理しませんあなたはフォーマット文字列内代入抑制オペレータを利用することができます。" %99[^\n]%*c"
%*c
が文字%c
を読み取るための書式指定子ですが、'*'
(代入抑制オペレータ)を含むことによって、あなたはscanf
への読み取りを伝え、捨てます文字。
ユーザ入力時に正しいフォーマット指定子を入力するだけでは不十分です。 VALIDATEあなたは実際にあなたが期待した入力を受け取っていなければなりません。いずれの入力ルーチンでも、少なくとも、scanf
(またはfgets
またはgetline
など)の戻り値をチェックすることを意味します。 scanf
の場合、戻り値は "一致カウント"です。これは、フォーマット文字列に基づいて実行された成功したコンバージョン数のです。例えば%s
(または%[^\n]
)は、1回の変換要求を構成します。 (割り当て抑制演算子に関連付けられている変換は一致カウントに含まれません)したがって、期待される戻り値はフォーマット文字列の変換数です。その一緒に入れて、あなたとあなたのinputtext
を扱うことができる:
printf ("What should be written in the text file? "); /* prompt */
/* validate user input -- limit to 99 chars (+1 for nul char) */
if (scanf (" %99[^\n]%*c", inputtext) != 1) {
fprintf (stderr, "error: invalid input (inputtext).\n");
return 1;
}
することは同じこともfilename
のために働くと思いませんか?回答:No.なぜですか?ユーザーが入力した後に".txt"
をfilename
に追加する予定ですか? ".txt"
にはいくつの文字が含まれていますか?回答:4
(合計文字列は1
で、ヌル終端文字はです)。あなたは何をfilename
に限定しなければなりませんか? " %95[^\n]%*c"
ファイルI/Oを実行するには、いくつかの選択肢があります。これまでのところ、fstreamのバッファ付き入出力機能は、基本的なテキストI/Oに最も一般的です。ファイルの読み込みまたは書き込みを行うには、まずFILE
ストリームを開く必要があります。 FILE *pointer
を宣言してからfopen
を呼び出し、ファイルの検証を行うために返される値(pointer
の値)を確認して正常に開きました。 stdin
またはstdout
への書き込みと同じように、同じ規則、書式指定子などがファイルの読み書きに適用されます。これらはすべてCの観点からのファイルなので、 、あなたは次のような何かができることを念頭に置いて
: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXC = 100 };
int main (void) {
/* declare and initialize variables */
char filename[MAXC] = "", inputtext[MAXC] = "";
FILE *fp = NULL;
printf ("What is the .txt file name? "); /* prompt */
/* validate user input -- limit to 95 chars */
if (scanf (" %95[^\n]%*c", filename) != 1) {
fprintf (stderr, "error: invalid input (filename).\n");
return 1;
}
strcat (filename, ".txt"); /* +4 chars = 99 chars */
/* open file/validate file open for reading */
if (!(fp = fopen (filename, "w"))) {
fprintf (stderr, "error: file open failed '%s'.\n", filename);
return 1;
}
printf ("What should be written in the text file? "); /* prompt */
/* validate user input -- limit to 99 chars (+1 for nul char) */
if (scanf (" %99[^\n]%*c", inputtext) != 1) {
fprintf (stderr, "error: invalid input (inputtext).\n");
return 1;
}
/* output status to stdout & inputtext to fp */
printf ("\nwriting to '%s'\n%s\n", filename, inputtext);
fprintf (fp, "%s\n", inputtext);
if (fclose (fp)) /* close file - validate stream close */
fprintf (stderr, "error: on file stream close.\n");
return 0;
}
注:ファイルへを書いした後、流れを保証するためにfclose
のリターンを確認することが重要です書き込み中にエラーが発生しませんでした。
$ cat dat/inputtext.txt
A quick brown fox jumps over the lazy dog.
は終わったコードを見てみましょう:
使用例/出力
$ ./bin/inputtext
What is the .txt file name? dat/inputtext
What should be written in the text file? A quick brown fox jumps over the lazy dog.
writing to 'dat/inputtext.txt'
A quick brown fox jumps over the lazy dog.
は、ファイルの内容を確認してください(終値は、あなたからの読み取りストリームのために、その心配はありません)私が知っている場合は、の任意の文字に関するご質問があります。誰もがちょっとした助けを必要とします。私が伝えることができる最も重要なことは、コード化するすべての文字を遅くして理解し、コンパイラの警告を読んで理解することです(すべてを修正します)。 、 調べる。 Linux/Unixの場合はman function
、Windowsの場合はMSDNを検索してください(例:scanf_s,...)。彼らはどのようなタイプと要件がすべての関数のすべてのパラメータにあるのかを合理的に明確な言葉で伝えています(そして、多くの例があります)。
あなたのコーディングで幸運を祈る。
コードにはいくつかの問題があります。私はこれをチェックすることをお勧めします:http://stackoverflow.com/documentation/c/507/files-and-io-streams/3468/open-and-write-to-file#t=201607270249425731337 – pah
あなたは*配列を作成します'char * fileName [100];'、 'char fileName [100] =" ";'でchar *へのポインタ100個で十分です。 –
最初の問題は、 'scanf_s()'に文字列変数の明示的な長さ引数が必要であり、あなたがそれを指定していないことです。あなたは '' file fileName [100] ''に型を修正する必要がありますが、 '' printf_s( "%99s"、fileName、sizeof(fileName))!= 1){...エラーを報告して続行しません} ; '(100文字のポインタではなく100文字)。その後、問題は続きます... –