参考文献:高橋麻奈著『やさしいC第5版』
gets文
ダンディ。いままでのscanfでは間に空白が入った文字列は入力できなかったが、ゲッツ(本当はゲット・エスという読み方らしい)を使うと改行までの文章がまるまる入力できるようになる。
puts文
ゲッツが読み込んだ文字列を、そのまんま出力するための文。
\nをつけなくても、文字列の最後にはちゃんと改行してくれる。
しかし、今までお世話になったprintfが使えず、変換仕様による書式をつけられない。
EOF
エンド・オブ・ファイルの略。stdio.hに定義されているマクロやファイルの終端を表す。
文字を続けて入力し、それを出力するコード
文字列ではなく、一文字ずつ入出力したい場合はgetcharとputcharを用いる。
int ch;
printf("文字を続けて入力してください。\n")
while((ch = getchar()) != EOF)
{
putchar(ch);
}
バッファリング
ハードディスクなどにデータの入出力を行う際、時間を短縮するため一文字一文字ではなく、まとめておこなうこと。
gets関数とputs関数を使って、アルファベットの小文字を大文字にするコード
ちなみにgets関数は、バッファ・オーバーフロー(コンピュータのキャパシティを超えた膨大なデータの書き込み)を起こしやすく、現在のバージョンでは禁止されているらしい。禁じられし古の呪文。
逆に言えば、システムを破壊したいクラッカーなどが悪用していたりする。
#include
int main(void)
{
int i;
char test[100];
printf("一行の英文を入力してください。\n");
gets(test);
//testを文字の配列とする。
for(i=0; test[i]!='\0'; i++)
if(97 <= test[i] && test[i] <= 122)
test[i] -= 32; //前にもやったように小文字の文字コードから32を引くと大文字となる。
puts(test);
return 0;
}
getchar関数とputchar関数を使って、アルファベットの小文字を大文字にするコード
1行まとめてではなく、一文字一文字小文字を大文字に変換させたい場合。コンパイル結果はさっきのコードと同じ。
#include
int main(void)
{
int ch;
printf("文字を続けて入力してください。\n");
while((ch=getchar())!=EOF){
if(ch>=97&&ch<=122)ch-=32;
putchar(ch);
}
return 0;
}
ファイルの入出力
ファイルを扱う際には、①ファイルを開く(fopen)、②ファイルを編集する、③ファイルを閉じる(fclose)の3つの手順を踏む。
fopen(ファイルを開く)
ファイル名とオープンモードを指定して実行し、実行結果をファイルポインタに受け取る。
構文 FILE *ファイルポインタ = fopen("ファイル名","オープンモード");
例 FILE *fp = fopen("test.txt","w");
ファイルポインタ(ストリームポインタ)
ポインタを授業では割愛していて、いきなり言われても意味不明なのだが、変数のデータをメモリに記憶させる際、どの領域に格納されたかの所在地をアドレスといい、このアドレスを記憶する変数をポインタというらしい。
メモリの中のデータを編集する際に使用する。
何らかの理由でファイルがオープンできなかった場合(ハードディスクの容量が足りなくなったなど)は、ファイルポインタにはNULLポインタというポインタが返ってくる(NULL文字とは別物なので注意!)。
オープンモード
ファイルをオープンする際の設定のようなもの。
"w" ライト。書き込み用にテキストファイルを白紙で開く。
"r" リード。読み込み用にテキストファイルを開く。
"a" アペンド。追記用にテキストファイルを開く。
"w+" 更新用にテキストファイルを開く(新規作成)。
"r+" 更新用にテキストファイルを開く。
"a+" 更新のため追記用のテキストファイルを開く。
"wb" 書き込み用にバイナリファイル(テキストファイル以外のファイル)を開く。
"rb" 読み込み用にバイナリファイルを開く。
"ab" 追記用にバイナリファイルを開く。
fclose(ファイルを閉じる)
ファイルを閉じる構文は割とシンプルで助かる。
構文 fclose(ファイルポインタ);
例 fclose( fp );
fputs(ファイルへの出力)
1行の文字列をファイルに書き込む。
ややこしいのは、putsのときのように、自動的に改行をしてくれないので\nをつけなければならない。だったら全部\nアリで統一してくれ!
構文 fputs( 文字列, ファイルポインタ );
例 fputs("Hello!", fp);
fgets(ファイルからの入力)
1行の文字列をファイルから読み取る。
構文 fgets( 変数, 読み込む最大文字数, ファイルポインタ );
例 fgets(str, 256, fp);
test1.txtの内容をそのままtest2.txtにコピーするコード
2つのテキストファイルがあり、1つは読み込み用として、もう一つは書き込み用として開く必要がある。
ファイルには10行のテキストが入っているという設定なので、マクロのNUMは10にする。
#include
#define NUM 10
int main(void)
{
int i;
FILE *fp1, *fp2;
char test[NUM];
//ファイル1は読み込み用として開く
fp1 = fopen("test1.txt","r");
//ファイル2は書き込み用として開く
fp2 = fopen("test2.txt","w");
if(fp1==NULL || fp2==NULL)
{
printf("ファイルを開けませんでした。\n");
return 1;
}
for(i=0; i<10; i++) //for文を使ってコピーを10行分繰り返す。
{
fgets(test, NUM-1, fp1);
fputs(test, fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}
受験者数と人数分の点数が保存されているファイル1から最高点数、最低点数、点数の合計、平均をファイル2に出力するプログラム
出力するデータに変換仕様(%dなど)が必要なので、そもまま文字列を出力しちゃうfputsではなく、fprintfを用いる。
#include
int main(void)
{
int i,num,tmp,max,min,sum;
FILE *fp1, *fp2;
fp1 = fopen("file1.txt","r");
fp2 = fopen("file2.txt","w");
if(fp1==NULL || fp2==NULL)
{
printf("ファイルを開けませんでした。\n");
return 1;
}
fscanf(fp1,"%d",&num);
max = -1000000;
min = 1000000;
sum = 0;
for(i=0; i
fscanf(fp1,"%d",&tmp);
if(max < tmp)
max = tmp;
if(min > tmp)
min = tmp;
sum = sum + tmp;
}
fprintf(fp2,"最高点数:%d\n",max);
fprintf(fp2,"最低点数:%d\n",min);
fprintf(fp2,"最高合計:%d\n",sum);
fprintf(fp2,"平均点数:%.1f\n",(double)sum/(double)num);
fclose(fp1);
fclose(fp2);
return 0;
}
個人情報が保存されたtext.txtというテキストファイルのデータを出力するコード
最後の課題。コンパイル数が恐ろしいことになった。
#include < stdio.h >
#include < stdlib.h >
int main(void){
FILE *fp;
char name[256];
int age;
double weight;
char e_mail[256];
//ファイルのデータの読み込み
fp = fopen("text.txt", "r");
if(fp == NULL)
{
printf( "ファイルが開けませんでした.\n");
}
fscanf(fp, "name: %255[^\n]\n" , name);
fscanf(fp, "age: %d\n" , &age);
fscanf(fp, "weight: %lf\n" , &weight);
fscanf(fp, "e-mail: %255[^\n]\n" , e_mail);
fclose(fp);
//ファイルのデータの出力
printf("氏名: %s\n", name);
printf("年齢: %d\n", age);
printf("体重: %.1f\n", weight);
printf("Eメール: %s\n", e_mail);
return 0;
}
理系分補充ということで、コンピュータやったわけだけど、いざやってみたら、勉強してる印象は英語に近かった…(´;ω;`)