■要求定義
– 空のフォルダを削除する
#include <stdio.h> #include <sys/stat.h> int main(){ char *dir = "./newfolder"; rmdir(dir); return 0; }
$ ./dev
フォルダの中にファイルが入っているときは、rmdirでは削除されない。
linuxコマンドとcの標準ライブラリ関数がネーミングが同じ場合は面白みがないな。
随机应变 ABCD: Always Be Coding and … : хороший
■要求定義
– 空のフォルダを削除する
#include <stdio.h> #include <sys/stat.h> int main(){ char *dir = "./newfolder"; rmdir(dir); return 0; }
$ ./dev
フォルダの中にファイルが入っているときは、rmdirでは削除されない。
linuxコマンドとcの標準ライブラリ関数がネーミングが同じ場合は面白みがないな。
■要求定義
– ファイルを作成する
■検討
– touchはファイルの中身は書かないから、fopen, fcloseだけで良いか?
#include <stdio.h> int main(){ FILE *fp; fp = fopen("test.txt", "w"); fclose(fp); return 0; }
$ ./dev
■追加
– コマンドラインで入力した値のファイルを作成する
#include <stdio.h> int main(){ char ss[256]; gets(ss); FILE *fp; fp = fopen(ss, "w"); fclose(fp); return 0; }
$ ./dev
hoge.txt
できました。
fopenの拡張子はテキストファイル(.dat, .txt, .c, .h)、バイナリファイル(.exe, .jpg, .gif, .mpeg)どちらも可
なるほど、C言語はバイナリの概念がかなり出てくるな。。
■要求定義
– フォルダを作成する
– 許可属性を与える
#include <sys/stat.h> int main(){ char *dir = "./newfolder"; mkdir(dir, 0777); return 0; }
mkdir(dir)のみだと、too few arguments to function ‘mkdir’とエラーになる。
まーそのまんまだな。
■要求定義
– 消さずに画面を綺麗にする
■検討
– windowsでsystem(“cls”); で消せると書いてある。嫌な予感がするが、bionicでも動く?
#include#include int main(){ for(int idx=0; idx<10; idx++){ printf("%d\n", idx); } system("clear"); return 0; }
0
1
2
3
4
5
6
7
8
9
sh: 1: cls: not found
やっぱり。DOS/Windowsコマンドらしく、linuxには無いとのこと。
int main(){ for(int idx=0; idx<10; idx++){ printf("%d\n", idx); } system("clear"); return 0; }
これなら動くけど意味ないね。
エスケープシーケンシーとはターミナルを制御する制御文字
printf("\033[2J") //画面クリア
などがある。
system("\033[2J");
う〜ん、clearコマンドとはちょっと違うな。
■要求定義
– ファイルやフォルダをコピーする
– cp (移動元ファイル名/フォルダ名) (移動先ファイル名/フォルダ名)
#include <stdio.h> #include <stdlib.h> //汎用ライブラリ #include <string.h> int main(){ FILE *fpSrc, *fpDes, *fp; char ss[256], ch[50]; fpSrc = fopen("test.txt", "r"); fpDes = fopen("copy.txt", "w"); while(fgets(&ss, 256, fpSrc) != NULL){ printf("%s", ss); fwrite(ss, 1, 8, fpDes); } fclose(fpSrc); fclose(fpDes); printf("コピーしました。\n"); return 0; }
$ ./dev
asdf
1234コピーしました。
■考察
あれ、コピー先のデータはバイナリデータで入ってるな。
調べてみると、fwriteはバイナリデータの書き込みとのこと。
fwriteではなく、fputs()に変更します。
int main(){ FILE *fpSrc, *fpDes; char ss[256]; fpSrc = fopen("test.txt", "r"); fpDes = fopen("copy.txt", "w"); while(fgets(&ss, 256, fpSrc) != NULL){ printf("%s", ss); fputs(ss, fpDes); } fclose(fpSrc); fclose(fpDes); printf("コピーしました。\n"); return 0; }
コピーできました。
バイナリとは2進数データのこと。
■要求定義
– ファイルを移動させる
■ステップ1
– 標準ライブラリ関数であるrename関数を使う
#include <stdio.h> int main(){ rename("./test.c", "./hoge/test.c"); printf("移動しました。\n"); return 0; }
$ ./dev
移動しました。
移動できた事を確認。
■ステップ2
– ユーザ入力で$ mv ${FileName} ${MoveDir}となるので、コマンドラインからの入力を元に移動させたい
– 文字列の分割は”strtok”を使う。ポインタでファイル名s1, 異動先s2を指定する。
#include <stdio.h> #include <string.h> int main(){ char ss[256] = "./test.c ./hoge/test.c"; char *s1, *s2; s1 = strtok(ss, " "); s2 = strtok(NULL, " "); rename(s1, s2); printf("移動しました。\n"); return 0; }
■ステップ3
– gets()でコマンドラインから入力した値を取得して移動させたい
int main(){ // char ss[256] = "./test.c ./hoge/test.c"; char ss[256]; char *s1, *s2; gets(ss); s1 = strtok(ss, " "); s2 = strtok(NULL, " "); rename(s1, s2); printf("移動しました。\n"); return 0; }
$ ./dev
./test.c ./hoge/test.c
移動しました。
ほう、面白い。コマンドラインからの入力は、strtokで分割して処理すれば良いですな。
■要求定義
– ユーザ名の入力に合わせてカレントディレクトリを移動する
■検討事項
ディレクトリ一覧を取得し、ユーザ入力と一致したら移動か
#include <stdio.h> #include <string.h> // 文字列操作 #include <unistd.h> // standard symbolic constants and types int main(){ char pathname[512]; memset(pathname, '\0', 512); // memsetはバイトメモリブロックのセット char path[64] = "./hoge"; chdir(path); getcwd(pathname, 512); // getcwdはカレントディレクトリ printf("%s\n",pathname); return 0; }
$ pwd
/home/vagrant/dev
$ ./dev
/home/vagrant/dev/hoge
cだと、chdir(path)でディレクトリを変更できる
■要求定義
– まずはファイル名一覧表示
– オプションは後から考える
■検討した事
標準関数でファイル名一覧の取得関数はないらしい
#include <stdio.h> #include <dirent.h> // format of directory entries int main(){ DIR *dir; struct dirent *dp; // 構造体 char path[64] = "./"; dir=opendir(path); // opendirはディレクトリオープン、 dirent.hが必要 for(dp=readdir(dir);dp!=NULL;dp=readdir(dir)){ // readdirはディレクトリ読み込み printf("%s\n",dp->d_name); } return 0; }
$ ./dev
.
dev
hello.c
..
forループでdp=readdir(dir);dp!=NULL;dp=readdir(dir)の書き方がよくわからんな。
さて、C言語の基礎を写経したので、ここから少しずつC言語を使って緩くOSを学んでいきたい
まずmac, windowsにもあるログイン処理から
■要求定義
– ユーザ名に一致したパスワードを入力し、一致していたらログイン
– 不一致の場合は、パスワードを再入力してくださいと表示
#include <stdio.h> #define User "hpscript" #define Password "asdf" int main(){ char s[5]; while(1){ printf("%sさん、パスワードを入力してください。\n", User); gets(s); if(strcmp(s, Password)==0){ printf("ログイン成功しました。\n"); break; } else { printf("%sさん、パスワードを入力してください。\n", s); } } return 0; }
$ ./dev
hpscriptさん、パスワードを入力してください。
aaaa
aaaaさん、パスワードを入力してください。
hpscriptさん、パスワードを入力してください。
asdf
ログイン成功しました。
文字列の比較は、strcmpを使用する
if(s == Password){} としても、trueにならない。
while(1)で無限ループにして、一致した場合はbreakでループから抜ける。
なるほど、型の宣言するところとか、色々頭使うなー
PCが記憶装置を制御している
– データ授受の為の情報通路: データ線、データバスと呼ばれる
– 読み出し・書込みの制御信号: R/Wを通告する
– 記憶装置のどの位置を選択するかのアドレス線
基本記憶素子をメモリセルという
主記憶装置の構造は
1. アドレス選択部
2. 制御部
3. 記憶部: 一つのアドレスに1バイト
RAM
L SRAM: 高速アクセス、フリップフロップ、バイポーラ型、MOS型のトランジスタが用いられている
L DRAM: コンデンサに電荷を蓄える
フラッシュメモリ
大容量で書き換え可能回数の多い
キャッシュメモリ
主記憶装置とCPUの間に小容量の高速メモリを入れる