[C言語]CSVから郵便番号読み取り

– ユーザが郵便番号7桁を入力すると市区町村を返したい
– 郵便番号のデータは郵便局のHPで配布している
zipcode
– 全国一括データは12万件ある
-> 今回は東京都のデータを使用する
– データの中身を見ると、C列が郵便番号、G列が東京都、H列が区/市、I列が町村となっている。

まずExcelのデータ読み取りからか? ubuntuに”13TOKYO.CSV”を配置する。

#include <stdio.h>
#include <string.h> // strtokに必要
#include <stdlib.h>
#define MAX 2048

int main(void){
	FILE *fp;
	char buf[2048] = {0};
	char *ary[3];
	char fname[] = "13TOKYO.CSV";
	int i;
	
	if((fp=fopen(fname,"r"))!=NULL){
		i = 0;
		while(fgets(buf, 2048, fp) != NULL){
			ary[0] = strtok(buf,",");  // ','を区切りに分解する
			ary[1] = strtok(NULL,",");
			ary[2] = strtok(NULL,",");
			printf("%s %s %s\n", ary[0],ary[1],ary[2]);
			i++;
			if(i > 5){
				break;
			}
		}
	}
	fclose(fp);

	return 0;
}

$ ./main
1000000 ?????s ???c??
1020072 ?????s ???c??
1020082 ?????s ???c??
1010032 ?????s ???c??
1010047 ?????s ???c??
1000011 ?????s ???c??

文字化けする
gccを変えてみたがダメ
$ gcc -o main main.c -finput-charset=UTF-8 -fexec-charset=CP932

csvをUTF-8の文字コードで保存してみる。

$ ./main
1000000 東京都 千代田区
1020072 東京都 千代田区
1020082 東京都 千代田区
1010032 東京都 千代田区
1010047 東京都 千代田区
1000011 東京都 千代田区

来た!
CSVはstrtokでカンマ区切りで取得すればOKとのことです。

[C言語]インチ計算

1inchは2.54cm
ということは1cm = 0.393701 inch

#include <stdio.h>
#include <stdlib.h>

int main(void){
	int cm;
	double inch;

	printf("cmを入力してください。\n"); fflush(stdout); 
	scanf("%d", &cm);

	inch = cm * 0.393701;

	printf("%dcmは%.3finch\n", cm, inch);

	return 0;
}

$ ./main
cmを入力してください。
14
14cmは5.512inch

きゃーーーー
あ、0.393701で掛けるよりも、2.54で割る方が一般的のようです。

[C言語]分計算

#include <stdio.h>
#include <stdlib.h>

int main(void){
	char c[128];
	int m,h,m2;

	printf("時間: \n"); fflush(stdout); // stream が指すストリームにおいて,まだ書き込まれていないデータを書き込み
	gets(c); h=atoi(c);

	printf("分: \n"); fflush(stdout);
	gets(c); m=atoi(c);

	m2 = h*60 + m;

	printf("%d時間%d分 -> %d分: \n", h, m, m2);

	return 0;
}

$ ./main
時間:
4
分:
25
4時間25分 -> 265分

[C言語]ホスト名

#include <stdio.h>

int main(void){
	char cpnm[MAX_COMPUTERNAME_LENGTH+1];
	DWORD len;

	len=MAX_COMPUTERNAME_LENGTH+1;

	GetComputerName(cpnm,&len);
	printf("this computer name is %s\n", cpnm);


	return 0;
}

$ gcc -o main main.c
main.c: In function ‘main’:
main.c:4:12: error: ‘MAX_COMPUTERNAME_LENGTH’ undeclared (first use in this function)
char cpnm[MAX_COMPUTERNAME_LENGTH+1];
^~~~~~~~~~~~~~~~~~~~~~~
main.c:4:12: note: each undeclared identifier is reported only once for each function it appears in
main.c:5:2: error: unknown type name ‘DWORD’
DWORD len;
^~~~~
main.c:9:2: warning: implicit declaration of function ‘GetComputerName’ [-Wimplicit-function-declaration]
GetComputerName(cpnm,&len);
^~~~~~~~~~~~~~~

GetComputerNameではなく、gethostnameか。

#include <stdio.h>
#include <unistd.h> // インプリメンテーション固有関数

int main(void){
	char hostname[128];

	gethostname(hostname, sizeof(hostname));

	printf("host name is %s\n", hostname);

	return 0;
}

$ ./main
host name is ubuntu-bionic

ほうー

[C言語]配列のアドレス

#include 

int main(void){
	char c[128] = "1234ABCDあいうえ";
	int i;

	printf("char型変数の値\n");
	printf("cの値:%s\n",c);
	printf("cのアドレス:%X\n",c);

	printf("配列要素c[i]の値とアドレス(16進数)\n");
	for(i=0; i<16; i++){
		printf("c[%2d]:値=%X アドレス=%X\n", i, c[i],&c[i]);
	}


	return 0;
}

$ ./main
char型変数の値
cの値:1234ABCDあいうえ
cのアドレス:E16367D0
配列要素c[i]の値とアドレス(16進数)
c[ 0]:値=31 アドレス=E16367D0
c[ 1]:値=32 アドレス=E16367D1
c[ 2]:値=33 アドレス=E16367D2
c[ 3]:値=34 アドレス=E16367D3
c[ 4]:値=41 アドレス=E16367D4
c[ 5]:値=42 アドレス=E16367D5
c[ 6]:値=43 アドレス=E16367D6
c[ 7]:値=44 アドレス=E16367D7
c[ 8]:値=FFFFFFE3 アドレス=E16367D8
c[ 9]:値=FFFFFF81 アドレス=E16367D9
c[10]:値=FFFFFF82 アドレス=E16367DA
c[11]:値=FFFFFFE3 アドレス=E16367DB
c[12]:値=FFFFFF81 アドレス=E16367DC
c[13]:値=FFFFFF84 アドレス=E16367DD
c[14]:値=FFFFFFE3 アドレス=E16367DE
c[15]:値=FFFFFF81 アドレス=E16367DF

メモリのアドレスは順番に入っていることがわかります。

[C言語]変数のアドレス

#include <stdio.h>

int main(void){
	int a=127;

	printf("int型変数の値\n");
	printf("10進数表示:%d\n",a);
	printf("16進数表示:%X\n",a);

	printf("int型変数のアドレス\n");
	printf("10進数表示:%d\n",&a);
	printf("1t進数表示:%X\n",&a);


	return 0;
}

$ ./main
int型変数の値
10進数表示:127
16進数表示:7F
int型変数のアドレス
10進数表示:489720900
1t進数表示:1D308C44

ポインタのアドレスは&、値参照は*
何度も繰り返さないと忘れる

[C言語]論理式(0 | 1)

#include <stdio.h>
#include <stdlib.h>

int main(void){
	char c[128];
	int a,b,m;

	printf("\n数字を二回入力して論理式を調べます\n");
	printf("aに好きな数字を入力してください。\n");
	printf("a=\n");gets(c);a=atoi(c);
	printf("bに好きな数字を入力してください。\n");
	printf("b=\n");gets(c);b=atoi(c);

	printf("\n aの値は%d, bの値は%d\n\n", a,b);

	m=(a==b);
	printf("論理式 a==b の値は%d\n",m);
	m=(a<b);
	printf("論理式 a<b の値は%d\n",m);
	m=(a>b);
	printf("論理式 a>b の値は%d\n",m);

	

$ ./main

数字を二回入力して論理式を調べます
aに好きな数字を入力してください。
a=
6
bに好きな数字を入力してください。
b=
2

aの値は6, bの値は2

論理式 a==b の値は0
論理式 ab の値は1

m=(a==b)と書いて、正の場合は1, 正しくない場合は0を表示する
true or falseに慣れていると、奇妙な感じがします。

[C言語]Shift_JIS

Shift_JISは日本語を含む文字列を表現するために用いられる文字コードの一つ
linuxにgetcheは無いののでgetcharを使う

#include <stdio.h>

int main(void){
	char c1, c2;

	c1 = getchar();
	c2 = getchar();
	
	printf("shift jis code:%02X%02X\n",c1, c2);

	return 0;
}

$ ./main
23
shift jis code:3233

ふむ、文字コードはC言語でなくても考えることなので、特に問題なし

[C言語]早打ちゲーム

時間計測にはclock()を使う

#include <stdio.h>
#include <time.h>

int main(void){
	
	clock_t start, end;

	start = clock();

	end = clock();
	printf("%f秒かかりました。\n", (double)(end-start)/CLOCKS_PER_SEC);

	return 0;
}

$ ./main
0.000002秒かかりました。

#include <stdio.h>
#include <time.h>

int main(void){
	int i;
	clock_t start, end;
	start = clock();
	printf("人口当たりの大根消費量ランキング1位はどこでしょう?\n1.岩手県, 2.千葉県, 3.群馬県\n");

	scanf("%d", &i);
	end = clock();

	if(i == 1){
		printf("正解です。%f秒かかりました。\n", (double)(end-start)/CLOCKS_PER_SEC);

	} else {
		printf("%f秒かかりました。入力内容が正しくありません。\n", (double)(end-start)/CLOCKS_PER_SEC);
	}
	
	return 0;
}

$ ./main
人口当たりの大根消費量ランキング1位はどこでしょう?
1.岩手県, 2.千葉県, 3.群馬県
1
正解です。0.000137秒かかりました。

なんかちゃうなぁ

[C言語]日時と時間

struct tmの構造体
struct tm {
int tm_sec; /* 秒 (0-60) */
int tm_min; /* 分 (0-59) */
int tm_hour; /* 時間 (0-23) */
int tm_mday; /* 月内の日付 (1-31) */
int tm_mon; /* 月 (0-11) */
int tm_year; /* 年 – 1900 */
int tm_wday; /* 曜日 (0-6, 日曜 = 0) */
int tm_yday; /* 年内通算日 (0-365, 1 月 1 日 = 0) */
int tm_isdst; /* 夏時間 */
};

#include <stdio.h>
#include <time.h>

int main(void){
	static char *week[] = {"日","月","火","水","木","金","土"};
	time_t now;
	struct tm
		*tm_now;

	now = time(NULL);
	tm_now = localtime(&now);
	printf("%4d年%2d月%2d日 %s曜日\n", tm_now->tm_year + 1900, tm_now->tm_mon+1, tm_now->tm_mday, week[tm_now->tm_wday]);
	printf("%2d時%2d分%2d秒\n", tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);

	return 0;
}

$ ./main
2020年 5月31日 日曜日
4時45分40秒

あれ、9時間+する方法がわからん。

時計

int main(void){
	static char *week[] = {"日","月","火","水","木","金","土"};
	time_t now, prev;
	struct tm
		*tm_now;

	prev = -1;
	for(;;){
		now = time(NULL);
		if(prev == now)
			continue;
		prev = now;
		tm_now = localtime(&now);
		printf("%2d時%2d分%2d秒\n", tm_now->tm_hour, tm_now->tm_min, tm_now->tm_sec);
	}

	return 0;
}