C言語学習4
昨日は苦C 17章から19章をやりました。
ポインタの理解が曖昧でなかなkコンパイルできませんでした。
番号 名前 テストの平均点
1 野比のび太 0
2 源静香 90
3 剛田武 40
4 骨川スネ夫 7
解答1
#include <stdio.h>
#include <string.h>
typedef struct {
char data[128];
} doraemons;
int main(void) {
doraemons character[5];
strcpy(character[0].data, "番号, 名前, テストの平均点\n");
strcpy(character[1].data, "1, 野比のび太, 0\n");
strcpy(character[2].data, "2, 源静香, 90\n");
strcpy(character[3].data, "3, 剛田武, 40\n");
strcpy(character[4].data, "4, 骨川スネ夫, 7\n");
FILE *file;
file = fopen("test.txt", "w");
if (file != NULL) {
for (int i = 0; i < 5; i++) {
fprintf(file, "%s", character[i].data);
}
fclose(file);
} else {
printf("ファイルを開けませんでした。\n");
}
return 0;
}
答え
#include <stdio.h>
int main(void)
{
FILE* fp;
fp = fopen("test.csv", "w");
fprintf(fp, "番号,名前,テストの平均点\n");
fprintf(fp, "1,野比のび太,0\n");
fprintf(fp, "2,源静香,90\n");
fprintf(fp, "3,剛田武,40\n");
fprintf(fp, "4,骨川スネ夫,70,\n");
fclose(fp);
return 0;
}
解答2
#include <stdio.h>
#include <string.h>
typedef struct {
int number;
char name[64];
int meanTestScore;
char data[128];
} doraemons;
int main(void) {
doraemons character[5];
strcpy(character[0].data, "番号, 名前, テストの平均点\n");
character[1].number = 1;
strcpy(character[1].name, "野比のび太");
character[1].meanTestScore = 0;
character[2].number = 2;
strcpy(character[2].name, "源静香");
character[2].meanTestScore = 90;
character[3].number = 3;
strcpy(character[3].name, "剛田武");
character[3].meanTestScore = 40;
character[4].number = 4;
strcpy(character[4].name, "骨川スネ夫");
character[4].meanTestScore = 70;
int charactersCount = sizeof(character) / sizeof(character[0]);
for (int i = 1; i < charactersCount; i++) {
sprintf(character[i].data, "%d, %s, %d\n", character[i].number,
character[i].name, character[i].meanTestScore);
}
FILE *file;
file = fopen("doraemonCharacters.csv", "w");
if (file != NULL) {
for (int i = 0; i < 5; i++) {
fprintf(file, "%s", character[i].data);
}
fclose(file);
} else {
printf("ファイルを開けませんでした。\n");
}
return 0;
}
chatGPTにリファクタリングしてもらった。
#include <stdio.h>
#include <string.h>
typedef struct {
int number;
char name[64];
int meanTestScore;
} doraemons;
int main(void) {
doraemons character[5] = {
{0, "", 0}, // ヘッダー行のためのダミーデータ
{1, "野比のび太", 0},
{2, "源静香", 90},
{3, "剛田武", 40},
{4, "骨川スネ夫", 70}
};
FILE *file = fopen("doraemonCharacters.csv", "w");
if (file != NULL) {
fprintf(file, "番号, 名前, テストの平均点\n");
for (int i = 1; i < 5; i++) {
fprintf(file, "%d, %s, %d\n", character[i].number,
character[i].name, character[i].meanTestScore);
}
fclose(file);
} else {
printf("ファイルを開けませんでした。\n");
}
return 0;
}
めちゃめちゃ短くなって笑った。
構造体の初期化ってブロック使って一気に全要素いけるんだな〜!
すごい!めっちゃ楽じゃん!
リファクタリングしてもらうと知らないこと教えてくれるから、これからコード書いたら毎回聞いてみようと思いました。
解答
#include <stdio.h>
#include <string.h>
enum {
nonOlimpicYear,
summerOlympicYear,
winterOlympicYear,
};
int findOlympicYear(int year);
int main(void) {
int year;
int isOlympicYear;
char message[128];
printf("西暦を入力してください: ");
scanf("%4d", &year);
isOlympicYear = findOlympicYear(year);
if (isOlympicYear == nonOlimpicYear) {
sprintf(message, "西暦%d年は、オリンピック開催年ではありません。",
year);
} else if (isOlympicYear == summerOlympicYear) {
sprintf(message, "西暦%d年は、夏季オリンピック開催年です。", year);
} else if (isOlympicYear == winterOlympicYear) {
sprintf(message, "西暦%d年は、冬季オリンピック開催年です。", year);
} else {
sprintf(message, "エラーです。");
}
printf("%s", message);
return 0;
}
int findOlympicYear(int year) {
int result;
if (year % 4 == 0) {
result = summerOlympicYear;
} else if (year % 2 == 0 && year % 4 != 0) {
result = winterOlympicYear;
} else {
result = nonOlimpicYear;
}
return result;
}
答え
#include <stdio.h>
int olympic(int year);
enum {
OLYMIPC_NON,
OLYMIPC_SUMMER,
OLYMIPC_WINTER,
};
int main(void)
{
int year, hold;
scanf("%d", &year);
hold = olympic(year);
switch (hold) {
case OLYMIPC_NON:
printf("開かれない\n");
break;
case OLYMIPC_SUMMER:
printf("夏季五輪\n");
break;
case OLYMIPC_WINTER:
printf("冬季五輪\n");
break;
};
return 0;
}
int olympic(int year)
{
if (year % 2 == 0) {
if (year % 4 == 0) {
return OLYMIPC_SUMMER;
} else {
return OLYMIPC_WINTER;
}
} else {
return OLYMIPC_NON;
}
}
chatGPTのアドバイス
#include <stdio.h>
enum OlympicType {
NonOlympicYear,
SummerOlympicYear,
WinterOlympicYear
};
int findOlympicYear(int year);
int main(void) {
int year, result;
printf("西暦を入力してください: ");
if (scanf("%4d", &year) != 1) {
printf("無効な入力です。\n");
return 1;
}
result = findOlympicYear(year);
switch (result) {
case SummerOlympicYear:
printf("西暦%d年は、夏季オリンピック開催年です。\n", year);
break;
case WinterOlympicYear:
printf("西暦%d年は、冬季オリンピック開催年です。\n", year);
break;
case NonOlympicYear:
default:
printf("西暦%d年は、オリンピック開催年ではありません。\n", year);
break;
}
return 0;
}
int findOlympicYear(int year) {
if (year % 4 == 0) {
return SummerOlympicYear;
} else if (year % 2 == 0) {
return WinterOlympicYear;
} else {
return NonOlympicYear;
}
}
アドバイスとリファクタリングを基に修正。
enum定数を大文字にしただけです。
#include <stdio.h>
#include <string.h>
enum {
OLYMPIC_NON,
OLYMPIC_SUMMER,
OLYMPIC_WINTER,
};
int findOlympicYear(int year);
int main(void) {
int year, result;
printf("西暦を入力してください: ");
if (scanf("%4d", &year) != 1) {
printf("無効な入力です。\n");
return 1;
}
result = findOlympicYear(year);
switch (result) {
case OLYMPIC_SUMMER:
printf("西暦%d年は、夏季オリンピック開催年です。", year);
break;
case OLYMPIC_WINTER:
printf("西暦%d年は、冬季オリンピック開催年です。", year);
break;
case OLYMPIC_NON:
printf("西暦%d年は、オリンピック開催年ではありません。", year);
break;
}
return 0;
}
int findOlympicYear(int year) {
if (year % 4 == 0) {
return OLYMPIC_SUMMER;
} else if (year % 2 == 0) {
return OLYMPIC_WINTER;
} else {
return OLYMPIC_NON;
}
}
解答
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[64];
int age;
int sex;
} people;
#define MAN "男性"
#define WOMEN "女性"
#define OTHER "その他"
int inputPeople(people *data, int i);
int printPeople(people *data, int i);
int main(void) {
people *data;
int dataElements = 10;
data = (people *)malloc(sizeof(people) * dataElements);
int i = 0;
do {
inputPeople(&data[i], i);
i++;
if (dataElements == i) {
dataElements += 10;
data = (people *)realloc(data, sizeof(people) * dataElements);
}
} while (data[i - 1].age != -1);
int count = i;
for (i = 0; i < count; i++) {
printPeople(&data[i], i);
}
free(data);
return 0;
}
int inputPeople(people *data, int i) {
printf("%d人目のデータを入力してください。\n", i + 1);
printf("名前: ");
scanf("%63s", data->name);
printf("年齢: ");
scanf("%3d", &data->age);
printf("性別 1:男性, 2:女性, 3,その他: ");
scanf("%1d", &data->sex);
return 0;
}
int printPeople(people *data, int i) {
char sex[64];
switch (data->sex) {
case 1:
strcpy(sex, MAN);
break;
case 2:
strcpy(sex, WOMEN);
break;
default:
strcpy(sex, OTHER);
break;
}
printf("%03d人目\t名前: %6s,\t年齢: %3d,\t性別: %2s\n", i + 1, data->name,
data->age, sex);
return 0;
}
答え
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[256];
int age;
int sex;
} People;
void InputPeople(People* data);
void ShowPeople(People data);
int main(void)
{
int i, count, datasize;
People* data;
datasize = 10;
data = (People*)malloc(sizeof(People) * datasize);
count = 0;
while (1) {
InputPeople(&data[count]);
if (data[count].age == -1)
break;
count++;
if (count >= datasize) {
datasize += 10;
data = (People*)realloc(data, sizeof(People) * datasize);
}
}
for (i = 0; i < count; i++) {
ShowPeople(data[i]);
}
free(data);
return 0;
}
void InputPeople(People* data)
{
printf("名前:");
scanf("%s", data->name);
printf("年齢:");
scanf("%d", &data->age);
printf("性別(1-男性、2-女性):");
scanf("%d", &data->sex);
printf("\n");
}
void ShowPeople(People data)
{
char sex[16];
printf("名前:%s\n", data.name);
printf("年齢:%d\n", data.age);
if (data.sex == 1) {
strcpy(sex, "男性");
} else {
strcpy(sex, "女性");
}
printf("性別:%s\n", sex);
printf("\n");
}
chatGPTのアドバイス
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[64];
int age;
int sex;
} People;
void InputPeople(People *data);
void ShowPeople(People data);
int main(void) {
int count = 0, dataSize = 10;
People *data = malloc(sizeof(People) * dataSize);
while (1) {
if (count >= dataSize) {
dataSize += 10;
data = realloc(data, sizeof(People) * dataSize);
}
InputPeople(&data[count]);
if (data[count].age == -1) break;
count++;
}
for (int i = 0; i < count; i++) {
ShowPeople(data[i]);
}
free(data);
return 0;
}
void InputPeople(People *data) {
printf("名前: ");
scanf("%63s", data->name);
printf("年齢: ");
scanf("%d", &data->age);
if (data->age == -1) return;
printf("性別 (1-男性、2-女性、その他): ");
scanf("%d", &data->sex);
}
void ShowPeople(People data) {
char sex[16];
switch (data.sex) {
case 1:
strcpy(sex, "男性");
break;
case 2:
strcpy(sex, "女性");
break;
default:
strcpy(sex, "その他");
break;
}
printf("%d人目\t名前: %s,\t年齢: %d,\t性別: %s\n", data.name, data.age,
sex);
}
do-while内でのif条件がよくないの気づいてなかった。
ループ文もdo-whileじゃなくてwhileで無限ループを作った方が条件がわかりやすくて読みやすい。
なんで ShowPeople関数の引数が People *dataじゃないのか聞いてみた。
ShowPeople関数は構造体の値を出力するだけだから、変更されないようにした方が確かに安全だな〜。
アドバイスをもらってリファクタリングしてもらうと、
どのように改善していけばいいか明確にわかるのでとてもいい!
これから20章をやって、終わったらC言語以外の学習をしようと思います。
この記事が気に入ったらサポートをしてみませんか?