#1
by 熊ー » 3年前
最近、あるc言語入門サイトを一通り終わったばかりのレベルの者です。
考えながら電話帳のプログラムを書いてみたのですが、gets_s,strncmp,fscanfが思った通りの動作をしません。
文法的なエラーも警告もないので何が間違っているのかわかりません。
touroku関数は最初の氏名電話番号は登録できるのですが、2回目の登録の際、fscanfで配列plarryにファイルを読み込んで配列内容が0だった場合、その配列要素に入力内容を代入するというイメージです。しかしデバッグモードのローカル変数を見ると氏名は読み込めますが電話番号は読み込めてないです。なぜかわかりません。
そして、strncmpで読み込んだ内容(0の場合)と入力内容が違う場合その配列要素に入力内容を代入するという書き方も、代入処理にならずスルーになってしまいます。
あと名前の入力のところで1回目のgets_s関数がスルーされてしまいます。swichのエンターが働いているのだと思いますが、どう対処すればよいでしょうか?
code
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
typedef struct {
char name[60];
unsigned int number;
}phoneLIst;
void touroku(void);
void search(void);
void dele(void);
int main(void) {
int a = 0;
printf("\n-----電話帳-----\n");
printf("新規登録 -- 1\n");
printf("検索 -- 2\n");
printf("削除 -- 3\n");
printf("終了 -- 他\n");
scanf_s("%d", &a);
switch (a) {
case 1:touroku();
break;
case 2:search();
break;
case 3:dele();
break;
default:
break;
}
printf("\n終了");
return 0;
}
void touroku(void) {
printf("10件まで登録可\n");
phoneLIst pl = { 0,0 };
phoneLIst plarry[10] = { 0,0 };
int i = 0;
printf("名前の入力 -- ");
gets_s( pl.name,60);
gets_s( pl.name, 60);
printf("\n番号入力(-)なし -- ");
scanf_s("%d",&pl.number);
FILE* fp = NULL;
fopen_s(&fp, "PhoneList.txt", "r+");
if (fp == NULL) { //ファイルがなければ書き込みモード
fopen_s(&fp, "PhoneList.txt", "w");
plarry[0] = pl;
if (fp != NULL) {
fprintf(fp, "氏名:%s,電話番号:%d\n", plarry.name, plarry.number);
printf("保存完了");
return;
}
else {
printf("ERROR");
return;
}
}
else if (fp != NULL) { //ファイルがあれば読み込み
while(fscanf(fp, "氏名:%s,電話番号:%d\n", plarry.name, &plarry.number)!=EOF){
//if(strncmp(plarry.name,pl.name,60) != 0) //読み込んだ内容と違う場合
if (plarry.name == 0) //読み込んだ内容が0の場合
{
plarry = pl;
break;
}
}
fseek(fp, 0, SEEK_SET);
for (int i = 0; i < 10; i++) {
fprintf(fp, "氏名: % s, 電話番号 : % d\n", plarry.name, plarry.number);
}
printf("登録完了");
fclose(fp);
}
else{
printf("登録不可");
}
return;
}
void search(void) {
phoneLIst pl = { 0 };
phoneLIst plarry[10] = { 0 };
int i = 0, j = 0;
printf("検索 名前の入力\n");
gets_s(pl.name, 60);
gets_s(pl.name, 60);
FILE* fp = NULL;
fopen_s(&fp, "PhoneList.txt", "r");
if (fp != NULL) {
while (fscanf(fp, "氏名:%s,電話番号:%d\n", plarry.name, &plarry[i].number) != EOF) {
if (strncmp(pl.name,plarry[i].name,60)==0) { //同じ名前があれば表示
printf("氏名:%s,電話番号:%d", plarry[i].name, plarry[i].number);
j++;
break;
}
}
}
else {
printf("電話帳なし\n");
return;
}
if (j>0) {
printf("該当なし");
}
return;
}
void dele(void) {
phoneLIst pl = { 0 };
phoneLIst plarry[10] = { 0 };
int a;
printf("電話帳リスト\n");
FILE* fp = NULL;
fopen_s(&fp, "PhoneList.txt", "r+");
int i = 0;
if (fp != NULL) {
while (fscanf(fp, "%s,%d", plarry[i].name, &plarry[i].number) != EOF) {
printf("番号[%d]氏名:%s,電話番号:%d", i, plarry[i].name, plarry[i].number);
}
printf("削除する番号の選択---");
scanf_s("%d", &a);
plarry[a] = pl;
fseek(fp, 0, SEEK_SET);
for (int i = 0; i < 10; i++) {
fprintf(fp, "氏名:%s,電話番号:%d", plarry[i].name, plarry[i].number);
if (plarry[i].name == 0) {
plarry[i] = pl;
break;
}
}
printf("登録完了");
fclose(fp);
}
return;
}
/code
最近、あるc言語入門サイトを一通り終わったばかりのレベルの者です。
考えながら電話帳のプログラムを書いてみたのですが、gets_s,strncmp,fscanfが思った通りの動作をしません。
文法的なエラーも警告もないので何が間違っているのかわかりません。
touroku関数は最初の氏名電話番号は登録できるのですが、2回目の登録の際、fscanfで配列plarryにファイルを読み込んで配列内容が0だった場合、その配列要素に入力内容を代入するというイメージです。しかしデバッグモードのローカル変数を見ると氏名は読み込めますが電話番号は読み込めてないです。なぜかわかりません。
そして、strncmpで読み込んだ内容(0の場合)と入力内容が違う場合その配列要素に入力内容を代入するという書き方も、代入処理にならずスルーになってしまいます。
あと名前の入力のところで1回目のgets_s関数がスルーされてしまいます。swichのエンターが働いているのだと思いますが、どう対処すればよいでしょうか?
code
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
typedef struct {
char name[60];
unsigned int number;
}phoneLIst;
void touroku(void);
void search(void);
void dele(void);
int main(void) {
int a = 0;
printf("\n-----電話帳-----\n");
printf("新規登録 -- 1\n");
printf("検索 -- 2\n");
printf("削除 -- 3\n");
printf("終了 -- 他\n");
scanf_s("%d", &a);
switch (a) {
case 1:touroku();
break;
case 2:search();
break;
case 3:dele();
break;
default:
break;
}
printf("\n終了");
return 0;
}
void touroku(void) {
printf("10件まで登録可\n");
phoneLIst pl = { 0,0 };
phoneLIst plarry[10] = { 0,0 };
int i = 0;
printf("名前の入力 -- ");
gets_s( pl.name,60);
gets_s( pl.name, 60);
printf("\n番号入力(-)なし -- ");
scanf_s("%d",&pl.number);
FILE* fp = NULL;
fopen_s(&fp, "PhoneList.txt", "r+");
if (fp == NULL) { //ファイルがなければ書き込みモード
fopen_s(&fp, "PhoneList.txt", "w");
plarry[0] = pl;
if (fp != NULL) {
fprintf(fp, "氏名:%s,電話番号:%d\n", plarry[i].name, plarry[i].number);
printf("保存完了");
return;
}
else {
printf("ERROR");
return;
}
}
else if (fp != NULL) { //ファイルがあれば読み込み
while(fscanf(fp, "氏名:%s,電話番号:%d\n", plarry[i].name, &plarry[i].number)!=EOF){
//if(strncmp(plarry[i].name,pl.name,60) != 0) //読み込んだ内容と違う場合
if (plarry[i].name == 0) //読み込んだ内容が0の場合
{
plarry[i] = pl;
break;
}
}
fseek(fp, 0, SEEK_SET);
for (int i = 0; i < 10; i++) {
fprintf(fp, "氏名: % s, 電話番号 : % d\n", plarry[i].name, plarry[i].number);
}
printf("登録完了");
fclose(fp);
}
else{
printf("登録不可");
}
return;
}
void search(void) {
phoneLIst pl = { 0 };
phoneLIst plarry[10] = { 0 };
int i = 0, j = 0;
printf("検索 名前の入力\n");
gets_s(pl.name, 60);
gets_s(pl.name, 60);
FILE* fp = NULL;
fopen_s(&fp, "PhoneList.txt", "r");
if (fp != NULL) {
while (fscanf(fp, "氏名:%s,電話番号:%d\n", plarry[i].name, &plarry[i].number) != EOF) {
if (strncmp(pl.name,plarry[i].name,60)==0) { //同じ名前があれば表示
printf("氏名:%s,電話番号:%d", plarry[i].name, plarry[i].number);
j++;
break;
}
}
}
else {
printf("電話帳なし\n");
return;
}
if (j>0) {
printf("該当なし");
}
return;
}
void dele(void) {
phoneLIst pl = { 0 };
phoneLIst plarry[10] = { 0 };
int a;
printf("電話帳リスト\n");
FILE* fp = NULL;
fopen_s(&fp, "PhoneList.txt", "r+");
int i = 0;
if (fp != NULL) {
while (fscanf(fp, "%s,%d", plarry[i].name, &plarry[i].number) != EOF) {
printf("番号[%d]氏名:%s,電話番号:%d", i, plarry[i].name, plarry[i].number);
}
printf("削除する番号の選択---");
scanf_s("%d", &a);
plarry[a] = pl;
fseek(fp, 0, SEEK_SET);
for (int i = 0; i < 10; i++) {
fprintf(fp, "氏名:%s,電話番号:%d", plarry[i].name, plarry[i].number);
if (plarry[i].name == 0) {
plarry[i] = pl;
break;
}
}
printf("登録完了");
fclose(fp);
}
return;
}
/code