Работа со структурами или как я учился писать читабельный код

в 9:15, , рубрики: Песочница, Программирование, Совершенный код, метки: ,

С чего все началось

Я студент технического университета и учусь по направлению: «Высшая математика, информатика и математическое моделирование». Так как я учусь только на втором курсе — мой код совершенным назвать очень сложно. В прошлом семестре мы изучали такую дисциплину как «Современные парадигмы программирования». На одной из лекций мы рассматривали ООП на примере С++ и получили задание написать псевдо-музыкальную библиотеку с использованием структур.

Задание и первая версия программы

Программа должна была использовать структуру из 5-ти полей:
Поле №1: номер записи;
Поле №2: название трека;
Поле №3: имя исполнителя;
Поле №4: время звучания;
Поле №5: год записи.
Это должна была быть консольная программа, все данные в которую вводятся с клавиатуры или с текстового файла (по желанию писавшего). Вводимые данные сохраняются в память компьютера или в файл соответственно. Также программа должна исполнять такие команды:
Поиск: по номеру, названию, исполнителю, времени и году записи а также вывод всех записей на экран;
Изменение данных: удаление, редактирование и добавление новых записей;
Редактирование: возможность изменения всех полей кроме номера записи.

После почти двух недель лени был написан такой код (большинство выводимого текста написано транслитом, потому что в школе учил немецкий язык, а не английский):

То что может заставить Вас ужаснутся!
#include <cstdlib>
#include <iostream>
#include <string>

struct Muslib{
        int num;
        std::string name;
        std::string artist;
        std::string time;
        short jear;};

using namespace std;

int main(int argc, char *argv[])
{ Muslib muslib[100];
int kil;
cout<<"Vvedit' kil'kist pisen' yaku bazhaete dodaty u bazu dannyh: ";
cin>>kil;

for(int i=1; i<=kil; i++){
    muslib[i].num=i;
    cout<<"Input name: ";
    cin>>muslib[i].name;
    cout<<"Input artist: ";
    cin>>muslib[i].artist;
    cout<<"Enter time: ";
    cin>>muslib[i].time;
    cout<<"Enter jear: ";
    cin>>muslib[i].jear;
    cout<<endl;}
    
    string command;
    int n=-1;
    string str[15];
    while(command!="exit"){
        cout<<"Enter command (num, name, artist, time, jear, del, add, all, re). Dlya vyhoda vvedite 'exit'!"<<endl;
        cin>>command;
        if(command=="num"){
            cout<<"Enter num: ";
            cin>>n;
                cout<<"Number "<<muslib[n].num<<endl;
                cout<<"Name "<<muslib[n].name<<endl;
                cout<<"Artist "<<muslib[n].artist<<endl;
                cout<<"Time "<<muslib[n].time<<endl;
                cout<<"Jear "<<muslib[n].jear<<endl;
                }
        if(command=="name"){
            cout<<"Enter name: ";
            cin>>str[15];
            for(int i=0; i<kil; i++){
            if(str[15]==muslib[i].name){ 
                n=i;  
                cout<<"Number "<<muslib[n].num<<endl;
                cout<<"Name "<<muslib[n].name<<endl;
                cout<<"Artist "<<muslib[n].artist<<endl;
                cout<<"Time "<<muslib[n].time<<endl;
                cout<<"Jear "<<muslib[n].jear<<endl;
            }
            if(i==kil-1&&n==-1) cout<<"Element not found!"<<endl;
            }
        }
        if(command=="artist"){
            cout<<"Enter artist: ";
            cin>>str[10];
            for(int i=0; i<kil; i++){
            if(str[10]==muslib[i].artist){ 
                n=i;  
                cout<<"Number "<<muslib[n].num<<endl;
                cout<<"Name "<<muslib[n].name<<endl;
                cout<<"Artist "<<muslib[n].artist<<endl;
                cout<<"Time "<<muslib[n].time<<endl;
                cout<<"Jear "<<muslib[n].jear<<endl;
            }
            if(i==kil-1&&n==-1) cout<<"Element not found!"<<endl;
            }
        }
        if(command=="time"){
            cout<<"Enter time: ";
            cin>>str[10];
            for(int i=0; i<kil; i++){
            if(str[10]==muslib[i].time){ 
                n=i;  
                cout<<"Number "<<muslib[n].num<<endl;
                cout<<"Name "<<muslib[n].name<<endl;
                cout<<"Artist "<<muslib[n].artist<<endl;
                cout<<"Time "<<muslib[n].time<<endl;
                cout<<"Jear "<<muslib[n].jear<<endl;
            }
            if(i==kil-1&&n==-1) cout<<"Element not found!"<<endl;
            }
        }
        int jahr;
        if(command=="jear"){
            cout<<"Enter jear: ";
            cin>>jahr;
            for(int i=0; i<kil; i++){
            if(jahr==muslib[i].jear){ 
                n=i;  
                cout<<"Number "<<muslib[n].num<<endl;
                cout<<"Name "<<muslib[n].name<<endl;
                cout<<"Artist "<<muslib[n].artist<<endl;
                cout<<"Time "<<muslib[n].time<<endl;
                cout<<"Jear "<<muslib[n].jear<<endl;
            }
            if((i==kil-1)&&(n==-1)) cout<<"Element not found!"<<endl;
            }
        }
        if(command=="add"){//new elem
            int kill;
            cout<<"Vvedit' kilkist' novyh elementiv: ";
            cin>>kill;
            for(int i=kil+1; i<=kil+kill; i++){
            muslib[i].num=i;
            cout<<"Input name: ";
            cin>>muslib[i].name;
            cout<<"Input artist: ";
            cin>>muslib[i].artist;
            cout<<"Enter time: ";
            cin>>muslib[i].time;
            cout<<"Enter jear: ";
            cin>>muslib[i].jear;}
            kil=kil+kill;//kilkist elem
            }
            if(command=="all"){
                for(int i=1; i<=kil; i++){
                cout<<"Number "<<muslib[i].num<<endl;
                cout<<"Name "<<muslib[i].name<<endl;
                cout<<"Artist "<<muslib[i].artist<<endl;
                cout<<"Time "<<muslib[i].time<<endl;
                cout<<"Jear "<<muslib[i].jear<<endl;
                cout<<endl;
            }
                }
                
                if(command=="re"){//perepysat pole
                    cout<<"Enter num: ";
                    cin>>n;
                cout<<"Number "<<muslib[n].num<<endl;
                cout<<"Name "<<muslib[n].name<<endl;
                cout<<"Artist "<<muslib[n].artist<<endl;
                cout<<"Time "<<muslib[n].time<<endl;
                cout<<"Jear "<<muslib[n].jear<<endl;
                cout<<endl;
                string pole;
                cout<<"Vvedit' imya polya: ";
                cin>>pole;
                if(pole=="name") cin>>muslib[n].name;
                if(pole=="artist") cin>>muslib[n].artist;
                if(pole=="time") cin>>muslib[n].time;
                if(pole=="jear") cin>>muslib[n].jear;
                if(pole!="name"&pole!="artist"&pole!="time"&pole!="jear") cout<<"Pole not found :("<<endl;
                
                }
                if(command=="del"){
                    cout<<"Enter num: ";
                    cin>>n;
                muslib[n].num=0;
                for(int i=1; i<=kil; i++){
                    if(muslib[i].num!=i){
                muslib[i].num=i;
                muslib[i].name=muslib[i+1].name;
                muslib[i].artist=muslib[i+1].artist;
                muslib[i].time=muslib[i+1].time;
                muslib[i].jear=muslib[i+1].jear;
                muslib[i+1].num=0;
                }
                }
                kil=kil-1;
                }
}
    
    system("PAUSE");
    return EXIT_SUCCESS;
}

Несмотря ни на что, этот мой говнокод пыталось выдавать за свой большинство студентов нашей группы. Результатом этого стало нахождение более чем 10 багов и явное непонимание ими того, за что они пытаются получить оценку. Но свою главную задачу — получение оценки, эта программа выполнила на отлично.

Полная модернизация и версия 2.0

Прошло уже более 2-х месяцев после сдачи этой программы и месяц после сдачи экзамена по этому предмету. Сидя на каникулах дома и скучая за быстрым интернетом в общежитии, родилась гениальная идея переписать данную программу с использованием функций. Это было мое больное место. За полтора года обучения я так и не научился их использовать. Вооружившись 3G модемом и вечным google, начал искать примеры использования функций в С++. Через 3 часа серфинга по интернету и параллельного написания кода в Dev-C++, я смог понять как это работает. Прошло еще 7 часов и программа была практически полностью переписана с использованием функций. Теперь она была разделена на 3 файла и имела кода на 100 строк больше:

muslibrary.h

#ifndef MUSLIBRARY_H
#define MUSLIBRARY_H

#include <cstdlib>
#include <iostream>
#include <string>

using namespace std;

struct MusLib{
    int num;
    std::string name;
    std::string artist;
    std::string time;
    short jear;};

void AddPositionf(int,int);
void helpf(void);
void helpref(void);
void numf(int,int);
void namef(std::string,int);
void artistf(std::string,int);
void timef(std::string,int);
void jearf(short,int);
void ref(int,int);
void allf(int);
int delf(int,int);

#endif /* MUSLIBRARY_H */

MusikLibrary.cpp

#include "muslibrary.h"

int position;

int main(int argc, char *argv[])
{
    cout<<"Enter the number of positions: ";
    cin>>position;
    
    AddPositionf(0,position);  //Функция заполнения структуры
    string cmd;
    
    while(cmd!="exit"){
        cout<<"Enter command (Enter 'help' to help): ";
        cin>>cmd;
        if(cmd=="help") helpf(); //Функция помощи
        else if(cmd=="help_re") helpref(); //Функция помощи по переименованию
        else if(cmd=="num") {   //Поиск по номеру
            int number;
            cin>>number;
            numf(number,position);
        }
        else if(cmd=="name"){   //Поиск по имени
            std::string name;
            cin>>name;
            namef(name,position);
        }
        else if(cmd=="artist"){ //Поиск по артисту
            std::string artist;
            cin>>artist;
            artistf(artist,position);
        }
        else if(cmd=="time"){   //Поиск по времени
            std::string time;
            cin>>time;
            timef(time,position);
        }
        else if(cmd=="jear"){   //Поиск по году
            short jear;
            cin>>jear;
            jearf(jear,position);
        }
        else if(cmd=="re"){      //Переименовать
            int re;
            cin>>re;
            ref(re,position);
        }
        else if(cmd=="add"){     //Добавить
             int add;
             cin>>add;
             AddPositionf(position,position+add);
             position=position+add;
        }
        else if(cmd=="all")      //Показать все
             allf(position);
        else if(cmd=="del"){     //Удалить позицию
             int del;
             cin>>del;
             if(del>0&&del<position) {
                  delf(del,position);
                  position=position-1;
             }
        }
        else cout<<"Command not found!"<<endl; //Команда не найдена
    }
    
    //system("PAUSE");
    return EXIT_SUCCESS;
}

MusFunc.cpp

#include "muslibrary.h"

MusLib muslib[100];

void AddPositionf(int epos,int pos){
     if(epos>=0&&epos<pos){
                           for(int i=epos; i<pos; i++){
                                   muslib[i].num=i+1;
                                   cout<<"Enter name: ";
                                   cin>>muslib[i].name;
                                   cout<<"Enter artist: ";
                                   cin>>muslib[i].artist;
                                   cout<<"Enter time: ";
                                   cin>>muslib[i].time;
                                   cout<<"Enter jear: ";
                                   cin>>muslib[i].jear;
                                   cout<<endl;
                                   }
     }
}
       
void helpf(void){
    cout<<"__________________________________"<<endl;
    cout<<"|    command     |     action    |"<<endl;
    cout<<"|--------------------------------|"<<endl;
    cout<<"|              Find              |"<<endl;
    cout<<"|--------------------------------|"<<endl;
    cout<<"|num <number>    |find position  |"<<endl;
    cout<<"|name <name>     |find name      |"<<endl;
    cout<<"|artist <artist> |find artist    |"<<endl;
    cout<<"|time <hh:mm:ss> |find time      |"<<endl;
    cout<<"|jear (jear<9999)|find jear      |"<<endl;
    cout<<"|--------------------------------|"<<endl;
    cout<<"|      Operation of library      |"<<endl;
    cout<<"|--------------------------------|"<<endl;
    cout<<"|re <num>        |rename num     |"<<endl;
    cout<<"|del <num>       |delete num     |"<<endl;
    cout<<"|all             |print all      |"<<endl;
    cout<<"|add <number>    |add position   |"<<endl;
    cout<<"|--------------------------------|"<<endl;
    cout<<"|exit            |Exit           |"<<endl;
    cout<<"|________________________________|"<<endl;
}

void helpref(void){
    cout<<"__________________________________"<<endl;
    cout<<"|          Help Rename           |"<<endl;
    cout<<"|--------------------------------|"<<endl;
    cout<<"|Not rename for "Name"-enter NaN |"<<endl;
    cout<<"| ------ for "Artist"-enter NaN  |"<<endl;
    cout<<"| ------ for "Time"-enter NaN    |"<<endl;
    cout<<"| ------ for "Jear"-enter 0000   |"<<endl;
    cout<<"|________________________________|"<<endl;
}

void numf(int n, int pos){
    if(pos>n-1&&n!=0){
        cout<<"Position "<<muslib[n-1].num<<endl;
        cout<<"Name "<<muslib[n-1].name<<endl;
        cout<<"Artist "<<muslib[n-1].artist<<endl;
        cout<<"Time "<<muslib[n-1].time<<endl;
        cout<<"Jear "<<muslib[n-1].jear<<endl;
        cout<<endl;}
        else cout<<"Item position "<<n<<" is missing!n"<<endl;
}

void namef(std::string str,int pos){
    int notfound=0;
    for(int i=0; i<pos; i++){
        if(str==muslib[i].name){
            cout<<"Position "<<muslib[i].num<<endl;
            cout<<"Name "<<muslib[i].name<<endl;
            cout<<"Artist "<<muslib[i].artist<<endl;
            cout<<"Time "<<muslib[i].time<<endl;
            cout<<"Jear "<<muslib[i].jear<<"n"<<endl;
            notfound=notfound+1;
        }
    }
    if(notfound==0) cout<<"Elements named ""<<str<<"" not found!n"<<endl;
}

void artistf(std::string str,int pos){
    int notfound=0;
    for(int i=0; i<pos; i++){
        if(str==muslib[i].artist){
            cout<<"Position "<<muslib[i].num<<endl;
            cout<<"Name "<<muslib[i].name<<endl;
            cout<<"Artist "<<muslib[i].artist<<endl;
            cout<<"Time "<<muslib[i].time<<endl;
            cout<<"Jear "<<muslib[i].jear<<"n"<<endl;
            notfound=notfound+1;
        }
    }
    if(notfound==0) cout<<"Artist ""<<str<<"" not found!n"<<endl;
}

void timef(std::string str,int pos){
    int notfound=0;
    for(int i=0; i<pos; i++){
        if(str==muslib[i].time){
            cout<<"Position "<<muslib[i].num<<endl;
            cout<<"Name "<<muslib[i].name<<endl;
            cout<<"Artist "<<muslib[i].artist<<endl;
            cout<<"Time "<<muslib[i].time<<endl;
            cout<<"Jear "<<muslib[i].jear<<"n"<<endl;
            notfound=notfound+1;
        }
    }
    if(notfound==0) cout<<"Elements for time ""<<str<<"" not found!n"<<endl;
}

void jearf(short jear, int pos){
    int notfound=0;
    for(int i=0; i<pos; i++){
        if(jear==muslib[i].jear){
            cout<<"Position "<<muslib[i].num<<endl;
            cout<<"Name "<<muslib[i].name<<endl;
            cout<<"Artist "<<muslib[i].artist<<endl;
            cout<<"Time "<<muslib[i].time<<endl;
            cout<<"Jear "<<muslib[i].jear<<"n"<<endl;
            notfound=notfound+1;
        }
    }
    if(notfound==0) cout<<"Elements for jear ""<<jear<<"" not found!n"<<endl;
}

void ref(int num,int pos){
    if(num>0&&num<=pos){
        std::string str;
        short jear;
        cout<<"Rename help - enter command "help_re"!"<<endl;
        cout<<"Position "<<muslib[num-1].num<<endl;
        cout<<"Enter new Name: ";
        cin>>str;
        if(str!="NaN") muslib[num-1].name=str;
        cout<<"Enter new Artist: ";
        cin>>str;
        if(str!="NaN") muslib[num-1].artist=str;
        cout<<"Enter new Time: ";
        cin>>str;
        if(str!="NaN") muslib[num-1].time=str;
        cout<<"Enter new Jear: ";
        cin>>jear;
        if(jear!=0000) muslib[num-1].jear=jear;
    }
    else cout<<"Position not found!n"<<endl;
}
        
void allf(int pos){
     for(int i=0; i<pos; i++){
             cout<<"Position "<<muslib[i].num<<endl;
             cout<<"Name "<<muslib[i].name<<endl;
             cout<<"Artist "<<muslib[i].artist<<endl;
             cout<<"Time "<<muslib[i].time<<endl;
             cout<<"Jear "<<muslib[i].jear<<"n"<<endl;
     }
}

int delf(int num,int pos){
    muslib[num-1].num=0;
    for(int i=0; i<pos; i++){
            if(muslib[i].num!=i+1){
                 muslib[i].num=i+1;
                 muslib[i].name=muslib[i+1].name;
                 muslib[i].artist=muslib[i+1].artist;
                 muslib[i].time=muslib[i+1].time;
                 muslib[i].jear=muslib[i+1].jear;
                 muslib[i+1].num=0;
            }
    }
                
}

Второй вариант также не идеален, но по сравнению с первым будет куда лучше. Кроме того здесь я вооружился переводчиком и пытался писать максимально красиво. Всю критику и возможность упрощения или улучшения приму с пониманием.

Автор: sergak01

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js