Некорректная работа меню - C (СИ)
Формулировка задачи:
Почему "Choose smth" два раза выводится? И не понимаю, почему ввод выбора осуществляется именно так, через atoi (содрано с Шилдта). Почему нельзя сразу, напр., через scanf в int положить?
#include <stdio.h> #include <stdlib.h> #define MAX 100 struct instr { int num; char name[10]; int amount; double price; } data[MAX]; FILE *fp; int menu_select(); void enter(); void rewrite(); void print_d(); int main() { if((fp=fopen("ins.dat","ab"))==NULL) { printf("Error opening\n"); exit(1); } fclose(fp); char choice; //1 ввод данных в файл //2 обновление информации //3 печать всех данных for(;;) { choice=menu_select(); switch(choice) { case 1: enter(); break; case 2: rewrite(); break; case 3: print_d(); break; case 4: exit(0); } } return 0; } int menu_select() { int i; char s[3]; printf("1 - enter some data\n"); printf("2 - rewrite data\n"); printf("3 - print all data\n"); printf("4 - exit\n"); do { printf("Choose smth:\n"); gets(s); i=atoi(s); } while (i<1||i>4); return i; } void enter() { if((fp=fopen("ins.dat","r+"))==NULL) { printf("Error opening\n"); exit(1); } int x=0; // rewind(fp); do { fread(&data[x],sizeof(struct instr),1,fp); printf("data[%d].num=%d\n",x,data[x].num); x++; } while((data[x-1].num!=0) && x<MAX); x--; if(x==MAX) { puts("Theres no free space\n"); exit(1); } else printf("%d is free\n",x); data[x].num=x+1; printf("Enter the name\n"); scanf("%s",data[x].name); printf("Enter the amount\n"); scanf("%d",&data[x].amount); printf("Enter the price\n"); scanf("%lf",&data[x].price); fseek(fp,x*sizeof(struct instr),SEEK_SET); fwrite(&data[x],sizeof(struct instr),1,fp); fclose(fp); } void rewrite() { if((fp=fopen("ins.dat","ab+"))==NULL) { printf("Error opening\n"); exit(1); } fclose(fp); } void print_d() { if((fp=fopen("ins.dat","r"))==NULL) { printf("Error opening\n"); exit(1); } int x=0; rewind(fp); do { fflush(stdin); fscanf(fp,"%d%s%d%lf\n",&data[x].num,data[x].name,&data[x].amount,&data[x].price); printf("%-3d%-10s%-5d%-10.2f\n",data[x].num,data[x].name,data[x].amount,data[x].price); x++; } while(data[x].num!=0); fclose(fp); }
Решение задачи: «Некорректная работа меню»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> #define MAX 100 struct instr { int num; char name[10]; int amount; double price; }; FILE *fp; int menu_select(); void enter(); void rewrite(); void print_d(); #define file_name "ins.dat" int main() { char choice; //1 ввод данных в файл //2 обновление информации //3 печать всех данных for(;;) { choice=menu_select(); switch(choice) { case 1: enter(); break; case 2: rewrite(); break; case 3: print_d(); break; case 4: exit(0); } } return 0; } int menu_select() { int i; char s[3]; printf("1 - enter some data\n"); printf("2 - rewrite data\n"); printf("3 - print all data\n"); printf("4 - exit\n"); do { printf("Choose smth:\n"); scanf("%s",s); i=atoi(s); } while (i<1||i>4); return i; } void enter() { // открывает существующий файл или создает новый для дозаписи if((fp=fopen(file_name,"a+b"))==NULL){ printf("Error opening\n"); exit(1); } // устанавливает указатель на начало файла rewind(fp); int x=0; instr tempData; while(fread(&tempData,sizeof(instr),1,fp)){ printf("data[%d].num=%d\n",x,tempData.num); x++; } if(x==MAX) { printf("Theres no free space\n"); fclose(fp); return; } else printf("%d is free\n",MAX-x); tempData.num=x; printf("Enter the name\n"); scanf("%s",tempData.name); printf("Enter the amount\n"); scanf("%d",&tempData.amount); printf("Enter the price\n"); scanf("%lf",&tempData.price); fwrite(&tempData,sizeof(instr),1,fp); fclose(fp); } void rewrite() { // открывает существующий файл для чтения и записи if((fp=fopen(file_name,"r+b"))==NULL) { printf("Error opening file\n"); return; } char Name[10]={}; printf("Enter the name\n"); scanf("%s",Name); printf("the name is %s\n", Name); instr tempData; while(fread(&tempData,sizeof(instr),1,fp)){ if(!strcmp(tempData.name,Name)){ printf("The number of that thing is %d\n",tempData.num); printf("enter the new amount\n"); scanf("%d",&tempData.amount); fseek(fp,-sizeof(instr),SEEK_CUR); fwrite(&tempData,sizeof(instr),1,fp); fclose(fp); return; } } printf("Name is not found\n"); fclose(fp); } void print_d() { // открывает существующий файл для чтения if((fp=fopen(file_name,"rb"))==NULL) { printf("Error opening file\n"); return; } instr tempData; while(fread(&tempData,sizeof(instr),1,fp)){ printf("%-3d%-10s%-5d%-10.2lf\n",tempData.num,tempData.name,tempData.amount,tempData.price); } fclose(fp); }
Объяснение кода листинга программы
- Структура
instr
содержит поляnum
,name
,amount
иprice
. - Переменная
fp
используется для работы с файлом. - Функция
menu_select
используется для выбора действия из меню. - В функции
enter
происходит добавление нового элемента в файл. - В функции
rewrite
происходит изменение количества товара в файле. - Функция
print_d
используется для печати всех данных из файла. - В основной функции
main
происходит бесконечный цикл, в котором выбирается действие из меню. - Если выбран вариант 1, то вызывается функция
enter
. - Если выбран вариант 2, то вызывается функция
rewrite
. - Если выбран вариант 3, то вызывается функция
print_d
. - Если выбран вариант 4, то выполняется выход из программы.
- В функции
enter
используется функцияfopen
для открытия файла и функцияfclose
для его закрытия. - В функции
rewrite
используется функцияfopen
для открытия файла и функцияfclose
для его закрытия. - В функции
print_d
используется функцияfopen
для открытия файла и функцияfclose
для его закрытия. - В функции
enter
используется функцияfread
для чтения данных из файла и функцияfwrite
для записи данных в файл. - В функции
rewrite
используется функцияfread
для чтения данных из файла и функцияfwrite
для записи данных в файл. - В функции
print_d
используется функцияfread
для чтения данных из файла. - В функции
enter
используется функцияscanf
для ввода данных. - В функции
rewrite
используется функцияscanf
для ввода данных. - В функции
print_d
используется функцияprintf
для вывода данных на экран.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д