「C言語/ファイル入出力」の版間の差分
削除された内容 追加された内容
→ファイルのオープン: {{コラム|"stdafx.h"って何?}} タグ: 2017年版ソースエディター |
同じファイルを重複して fopen() しているバグ多数。 タグ: 2017年版ソースエディター |
||
29 行
FILE型へのポインタの宣言は、
<code> FILE *fp; </code>
の書式で行う。
さて、例えば、
<code> FILE *fp1; </code>
なら、fp1という名のFILE型へのポインタが作成される。
137 行
ファイルに何かデータを書き込むには、 <code>fprintf</code> という関数を使う。
fprintf の冒頭のfは、ファイル関係であることをあらわしている。最後のfは、もともとC言語には「printf」
147 ⟶ 146行目:
</syntaxhighlight>
で
172 ⟶ 171行目:
何か変数をファイルに書き込みたい場合、たとえば整数型の変数だとして、変数名が「
<syntaxhighlight lang="C">
int
</syntaxhighlight>
のように、どこかで宣言しておく。
そのあと、プログラム中にて変数「
そのあと、プログラムがコード内でのファイル書き込み実行場所にて
<syntaxhighlight lang="C">
fprintf(fp1, "%d \n",
</syntaxhighlight>
のようなコードを実行するように、ソースコードを記述すればいい。
207 ⟶ 206行目:
int main()
{
FILE *fp1 = fopen("test1.txt", "w");
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
char
printf("キーボードから文字列を入力してください。\n");
scanf("%s", &
printf("入力された文字列は %s です。 \n",
printf("これをファイルに書き込みます。 \n");
fprintf(fp1, "%s \n",
fclose(fp1);
printf("ファイルをクローズしました。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
282 ⟶ 279行目:
int main()
{
FILE *fp1 = fopen("test1.txt", "r");
if (fp1 == NULL) { // ここを読み取りモード"r"にするのを忘れないように
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
304 ⟶ 299行目:
fclose(fp1);
printf("ファイルをクローズしました。\n");
341 ⟶ 336行目:
int main()
{
FILE *fp1 = fopen("test1.txt", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
419 ⟶ 412行目:
int main()
{
FILE *fp1 = fopen("test1.txt", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
char buffer1[150];
445 ⟶ 435行目:
fclose(fp1);
printf("ファイルをクローズしました。\n");
486 ⟶ 476行目:
int main()
{
FILE *fp1 = fopen("test1.txt", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
char buffer1[150];
513 ⟶ 499行目:
fclose(fp1);
printf("ファイルをクローズしました。\n");
553 ⟶ 539行目:
次のようなデータである。
ファイル名「
<pre>
名前,番号
567 ⟶ 553行目:
さて、CSVファイルをカンマで区切って一つずつ読み取りたい場合、
fscanf
たとえば <code>%[^,]</code>なら、カンマ記号(,)の手前まで文字を読み込み、カンマ記号じたいは除いて読み込む。
585 ⟶ 571行目:
int main()
{
FILE *fp1 = fopen("sample.csv", "r");
if (fp1 == NULL) { // ここを読み取りモード"r"にするのを忘れないように
perror("ファイルを開けませんでした。\n");
//system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
612 ⟶ 596行目:
fclose(fp1);
printf("ファイルをクローズしました。\n");
return 0;
639 ⟶ 622行目:
なので、CSVの読み取りファイルをC言語で作る場合、fgets
しかし、fgets には、<code>%[^,]</code> のようなカンマで読み込み中止
なので、いったんfgetsで、その行の全体を読み込んだ後に、<code> strtok </code> という別の
<code> strtok </code>
なお、 <code> strtok </code>
書式は
<syntaxhighlight lang="C">
strtok(分解する文字列のある変数,"区切り文字にしたい文字")
</syntaxhighlight>
のようになる。
660 ⟶ 643行目:
CSVファイルを読み込ませたいなら、区切り文字にしたいのはカンマ記号なので、
<syntaxhighlight lang="C">
strtok(分解する文字列のある変数,",")
</syntaxhighlight>
となる。
666 ⟶ 649行目:
なお、<code> strtok </code> の第一引数を「NULL」にすると、前の文字の続きから読み込む。つまり
<syntaxhighlight lang="C">
strtok(NULL,"区切り文字にしたい文字")
</syntaxhighlight>
にすると、前の文字の続きから次ぎの区切り文字まで(その行に残りの区切り文字がない場合には行末まで)を読み込む。
682 ⟶ 665行目:
int main()
{
FILE *fp1 = fopen("sample.csv", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
733 ⟶ 714行目:
fclose(fp1);
printf("ファイルをクローズしました。\n");
789 ⟶ 770行目:
int main()
{
FILE* fp1 = fopen("sample.csv", "r");
if (fp1 == NULL) { // ここを読み取りモード"r"にするのを忘れないように
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
810 ⟶ 788行目:
char str[150];
};
struct seisekihyou row[20]; // 構造体配列の宣言
917 ⟶ 895行目:
int main()
{
FILE *fp1 = fopen("test1.txt", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
939 ⟶ 915行目:
fclose(fp1);
printf("ファイルをクローズしました。\n");
963 ⟶ 939行目:
int main()
{
FILE* fp1 = fopen("test1.txt", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
//fclose(fp1); // ここでクローズするとエラー
1,002 ⟶ 976行目:
<syntaxhighlight lang="C">
fp1 = fopen("test1.txt", "r");
if
fclose(fp1); // コメントアウトしないとエラーになる
1,033 ⟶ 1,007行目:
#include <stdlib.h> // Windowsでは「続行するには何かキーを押してください . . .」を表示するのに必要だった。
// #pragma warning(disable:4996) // Linux なので不要
int main()
{
FILE* fp1 = fopen("SettingFile.txt", "r"); // まず、読み込みモードで開く。
if
fclose(fp1);
}
1,056 ⟶ 1,028行目:
//system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 0;
}
</syntaxhighlight>
いっぽう、次のように改善して、読み込み失敗後のクローズ
(Fedora 31 で確認ずみ)
1,073 ⟶ 1,044行目:
int main()
{
FILE* = fopen("SettingFile.txt", "r"); // まず、読み込みモードで開く。
if (fp1 == NULL) { // 読み込みが失敗(NULL)の場合のブロック
perror("ファイルを開けませんでした。\n");
}
else {
1,092 ⟶ 1,060行目:
//system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 0;
}
</syntaxhighlight>
1,148 ⟶ 1,115行目:
この理由は、おそらく、読み込みに失敗した場合は、そもそも何もオープンしてないと判断なされるので、なので、失敗したぶんの <code> fopen </code> の1回ぶんは、カウントされないからです。
ただし、書き込みは通常、対象ファイルの有無に関係なく成功するので(対象ファイルの無い場合には自動作成するので)、なので、書き込みの
なので、上記のコードの直後に、もし <code> fgets </code> などの読み込み
上記のコードのあとに読み込みをしたい場合、再度 <code> fopen </code> の読み込みモードで開いてからでないと、 <code> fgets </code> などの読み込み
1,172 ⟶ 1,139行目:
int main()
{
FILE* fp1 = fopen("SettingFile.txt", "r"); // まず、読み込みモードで開く。
if
fp1 = fopen("SettingFile.txt", "w"); // 同名のファイルをそのまま fopen で開いてもいい
<!--ここにも fp1 が NULLを
printf("ファイルが存在しないので作成しています。ファイル名: SettingFile.txt \n");
fprintf(fp1, "書き込みテスト \n");
}
else {
}
fclose(fp1);
1,191 ⟶ 1,159行目:
//system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 0;
}
</syntaxhighlight>
1,198 ⟶ 1,165行目:
;実行例 (ファイルのない場合)
<pre>
ファイルが存在しないので作成しています。ファイル名: SettingFile.txt
ファイルを閉じました。
終了しています。
</pre>
1,206 ⟶ 1,173行目:
;実行例 (ファイルのある場合)
<pre>
ファイルはすでに存在しています。
ファイルを閉じました。
終了しています。
</pre>
;SettingFile.txtの中身
<pre>
書き込みテスト
</pre>
1,222 ⟶ 1,189行目:
いっぽう、もし <code>fclose(fp1);</code> を2回使っても、コンパイルは失敗してエラーになり、下記のように途中でエラーメッセージが表示されてしまい中断します。
<pre>
ファイルはすでに存在しています。
free(): double free detected in tcache 2
Aborted (コアダンプ)
1,258 ⟶ 1,225行目:
int main()
{
FILE *fp1 = fopen("totyuu.txt", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 ==
perror("ファイルを開けませんでした。\n");
//system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
}
else {
printf("ファイルをオープンしました。\n");
}
1,304 ⟶ 1,270行目:
fclose(fp1);
printf("ファイルをクローズしました。\n");
1,328 ⟶ 1,294行目:
== if文との組み合わせ ==
fgets
これはつまり、Linux標準のGCCでは、文字列の比較にイコール記号が使えないという事です。
1,403 ⟶ 1,369行目:
int main()
{
FILE *fp1 = fopen("test1.txt", "r"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
perror("ファイルを開けませんでした。\n");
system("pause");// 「続行するには何かキーを押してください . . .」の待機命令
return 1;
1,481 ⟶ 1,445行目:
setlocale(LC_ALL, "ja_JP.UTF-8"); //ロケール(地域)を設定する。
FILE* fp1 = fopen( "test1.txt", "r, ccs = UTF-8"); // ここを読み取りモード"r"にするのを忘れないように
if (fp1 == NULL) {
wprintf(L"ファイルを開けませんでした。\n");
return 1;
1,558 ⟶ 1,520行目:
_wsetlocale(LC_ALL, L""); //ロケール(地域)を設定する。
FILE* fp1 = _wfopen( L"test1.txt", L"r, ccs = UNICODE");
if (fp1 == NULL) { // ここを読み取りモード"r"にするのを忘れないように
wprintf(L"ファイルを開けませんでした。\n");
perror(0);
system("pause"); // 「続行するには何かキーを押してください . . .」の待機命令
return 1;
|