Некорректная работа меню - 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);
}

Объяснение кода листинга программы

  1. Структура instr содержит поля num, name, amount и price.
  2. Переменная fp используется для работы с файлом.
  3. Функция menu_select используется для выбора действия из меню.
  4. В функции enter происходит добавление нового элемента в файл.
  5. В функции rewrite происходит изменение количества товара в файле.
  6. Функция print_d используется для печати всех данных из файла.
  7. В основной функции main происходит бесконечный цикл, в котором выбирается действие из меню.
  8. Если выбран вариант 1, то вызывается функция enter.
  9. Если выбран вариант 2, то вызывается функция rewrite.
  10. Если выбран вариант 3, то вызывается функция print_d.
  11. Если выбран вариант 4, то выполняется выход из программы.
  12. В функции enter используется функция fopen для открытия файла и функция fclose для его закрытия.
  13. В функции rewrite используется функция fopen для открытия файла и функция fclose для его закрытия.
  14. В функции print_d используется функция fopen для открытия файла и функция fclose для его закрытия.
  15. В функции enter используется функция fread для чтения данных из файла и функция fwrite для записи данных в файл.
  16. В функции rewrite используется функция fread для чтения данных из файла и функция fwrite для записи данных в файл.
  17. В функции print_d используется функция fread для чтения данных из файла.
  18. В функции enter используется функция scanf для ввода данных.
  19. В функции rewrite используется функция scanf для ввода данных.
  20. В функции print_d используется функция printf для вывода данных на экран.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.286 из 5