Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
1 / 1 / 2
Регистрация: 24.09.2016
Сообщений: 144
1

Насколько плохо написан код?

02.10.2016, 18:41. Показов 1382. Ответов 26
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
написал программу с горем да пополам, но появился вопрос о ее качестве. насколько плохо она написана? стояла такая задача:
программа содержит массив строк, каждый из которых представляет собой запись про учетную запись пользователя, а каждое поле отделяется от другого двоеточием. известно, что первое поле сохраняет логин, пятое - имя и фамилию через запятую, а шестое - пароль
запросить логин пользователя. если логин неизвестный, то запросить логин заново. предусмотреть выход из программы если будет введено слово "bye". Если логин найдено в массиве, то вывести поздравление со значением имени и попросить ввести пароль. по результатам проверки пароля вывести на экран сообщение об успешной авторизации или дать пользователю дополнительную попытку. предусмотреть не более двух дополнительных попыток.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <string.h>
#include <fcntl.h>
#include <algorithm>
using namespace std;
int main () {
    setlocale (0, "");
    int i=0;
    char login[15], password[25];
    char* database[] = {"admin::::Владислав,Павленко:pavlenko2k16","VKopturov::::Владислав, Коптуров:KopturovV","MZadoyan::::Мирослав, Задоян:ZadoyanM",
    "DZinenko::::Данил, Зиненко:ZinenkoD","NIlchenko::::Николай, Ильченко:IlchenkoN","OKoval::::Олег, Коваль:KovalO","MMalukov::::Михаил, Малюков:MalukovM",
    "LMedzhina::::Любовь, Меджина:MedzhinaL","EYaremchenko::::Евгений, Яремченко:YaremchenkoE","DKolpakova::::Дарья, Колпакова:KolpakovaD"}; // Задаем пользователей
    start:
    for(;;){
        cout << " Введите логин: "; // Просим ввести логин
        cin.getline(login, 15); // Принимаем ввод
        if (strcmp(login, "bye") == 0)
        exit(0);
        for (i=0; i<10; i++) { // Проверяем логин в каждой строке
        char* num = strchr(database[i], ':'); //ищет номер первого входа : в строку
         if (strncmp(database[i],login,num-database[i])==0) // если логин и элементы до первого входа : совпадают - переход к приветствию
        goto privetstvie;
        }
}
privetstvie:
    
    cout<<"Введите пароль, ";
    string str = database[i];//присваиваем 
    string separ(","); //разделитель
    string::size_type pos = str.find(",");//ищем положение разделителя
    string first = str.substr(0, pos);//до разделителя
    string second = str.substr(pos+separ.length());//после разделителя
    string separate("::::"); //разделитель
    string::size_type pos3 = str.find("::::");//ищем положение разделителя
    string five = first.substr(0, pos3);//до разделителя
    string six = first.substr(pos3+separate.length());//после разделителя
    cout <<six<<endl;
    cout<<pos3<<" pos3";
    
    string separat(":"); //разделитель
    string::size_type pos2 = second.find(":");//ищем положение разделителя
    string third = second.substr(0, pos2);//до разделителя
    string fourth = second.substr(pos2+separat.length());//после разделителя
 
    int n=0;
    while (n<=2) { //ставим счетчик на 3 попытки
    n++;
    cout<<endl <<"Пароль: ";
    cin.getline(password, 25); //вводим пароль
    if (fourth==password) { //сравниваем пароль
    cout<<"Вход выполнен!";
    exit(0);
    }
}
goto start;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.10.2016, 18:41
Ответы с готовыми решениями:

Код написан в Dev C. Не работает в Visual. Как нужно переделать код?
Здравствуйте. Столкнулась с такой проблемой: код был написан в Dev C, но в Visual он выдаёт...

как исправить код на динамический массив-код уже написан только на статическом
#include &lt;iostream&gt; #include &lt;iostream&gt; #include &quot;string.h&quot; using namespace std; const...

правильно ли написан код в с++?
#include &lt;iostream&gt; #include &lt;map&gt; #include &lt;fstream&gt; using namespace std; int main() { ...

Неправильно написан код
Функция должна находить простые числа в заданном массиве. Выходит что-то вроде 003С100 .. void...

26
Эксперт С++
1624 / 954 / 782
Регистрация: 06.02.2016
Сообщений: 2,452
Записей в блоге: 31
02.10.2016, 18:53 2
Вообще goto лучше избегать
0
8 / 8 / 5
Регистрация: 28.10.2012
Сообщений: 135
02.10.2016, 18:59 3
Читать не удобно, скриптово. Бейте на функции типа таких: bool authorizе(), bool findindb(char* findname)
0
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
02.10.2016, 19:46 4
Лучший ответ Сообщение было отмечено pavlenko2k16 как решение

Решение

Цитата Сообщение от pavlenko2k16 Посмотреть сообщение
написал программу с горем да пополам, но появился вопрос о ее качестве. насколько плохо она написана?
pavlenko2k16, очень плохо.

По порядку:
  1. лучше использовать либо сишные строки, либо std::string
    ...
  2. для сишных строк в плюсах используй вместо
    C++
    1
    
    #include <string.h>
    вот такой вариант:
    C++
    1
    
    #include <cstring>
  3. для плюсовых строк (которые std::string) подключай вот этот заголовочный файл:
    C++
    1
    
    #include <string>
  4. лучше не использовать директиву using:
    C++
    1
    
    using namespace std;
    вместо этого лучше использовать либо объявления using:
    C++
    1
    2
    3
    
    using std::cout;
    using std::cin;
    using std::string;
  5. 10-12 строки - отвратительны, читать такое неудобно; хотя бы уж так:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    char* database[] =
        {
            "admin::::Владислав,Павленко:pavlenko2k16",
            "VKopturov::::Владислав, Коптуров:KopturovV",
            "MZadoyan::::Мирослав, Задоян:ZadoyanM",
            "DZinenko::::Данил, Зиненко:ZinenkoD",
            "NIlchenko::::Николай, Ильченко:IlchenkoN",
            "OKoval::::Олег, Коваль:KovalO",
            "MMalukov::::Михаил, Малюков:MalukovM",
            "LMedzhina::::Любовь, Меджина:MedzhinaL",
            "EYaremchenko::::Евгений, Яремченко:YaremchenkoE",
            "DKolpakova::::Дарья, Колпакова:KolpakovaD"
        };
  6. после операторов for, if else, while вставляй пробел, а фигурные скобки располагай согласно одному из стилей
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    // либо так:
    for ( ; ; ) {
        // some code here
    }
     
    //либо так:
    for ( ; ; )
    {
        // some code here
    }
  7. не стоит скупиться на пробелы и пустые строки, разделяющие логические блоки кода; отступы тоже стоит делать единообразно:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    for ( ; ; ) {
        cout << " Введите логин: "; // Просим ввести логин
        cin.getline( login, 15 ); // Принимаем ввод
        
        if ( strcmp( login, "bye" ) == 0 ) {
            exit( 0 );            
        }
     
        for ( i = 0; i < 10; i++ ) { // Проверяем логин в каждой строке
            char* num = strchr( database[i], ':' ); //ищет номер первого входа : в строку
            
            // если логин и элементы до первого входа : совпадают - переход к приветствию:
            if ( strncmp( database[i], login, num-database[i] ) == 0 ) {
                goto privetstvie;
            {
        }
    }
  8. вместо goto используй циклы
    ...
  9. логически и функционально связанные блоки кода выделяй в отдельные функции
6
1 / 1 / 2
Регистрация: 24.09.2016
Сообщений: 144
02.10.2016, 20:07  [ТС] 5
Спасибо огромное. буду учиться
0
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
02.10.2016, 20:13 6
Цитата Сообщение от pavlenko2k16 Посмотреть сообщение
буду учиться
Лучше всего по хорошим книгам.

За чистотой кода идти вот к этим ребятам:
  • Стив Макконнелл "Совершенный код"
  • Роберт Мартин "Чистый код"
0
Хитрая блондиночка $)
1472 / 988 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
02.10.2016, 20:41 7
Цитата Сообщение от gru74ik Посмотреть сообщение
По порядку:
Дополню: Данные лучше хранить в классах в виде списка объектов. vector думаю подойдет вполне.
Хотя... В данном случае учитывая что это список аккаунтов наверное map лучше всего.
0
_stanislav
02.10.2016, 21:01
  #8

Не по теме:


Цитата Сообщение от gru74ik Посмотреть сообщение
не стоит скупиться на пробелы и пустые строки, разделяющие логические блоки кода; отступы тоже стоит делать единообразно:
Таким советом наверно когда то Mr.X (здешний обитатель) пренебрег.

0
nmcf
02.10.2016, 21:06
  #9

Не по теме:

Цитата Сообщение от _stanislav Посмотреть сообщение
Таким советом наверно когда то Mr.X(здешний обитатель) пренебрег.
:good:

0
sourcerer
03.10.2016, 08:06
  #10

Не по теме:


_stanislav, у него своеобразный стиль, конечно. И к нему даже можно было бы привыкнуть. Но. Как всегда имеется но:

Цитата Сообщение от DrOffset Посмотреть сообщение
Самый главный недостаток, для которого не сработает позиция "о вкусах не спорят" - это полное отсутствие diff-friendly у такого форматирования. Во всех конторах используют системы контроля версий, и иногда приходится сводить изменения разных разработчиков. Так вот у такого форматирования зависимость символов не только горизонтальная, как обычно, но и вертикальная. Если у тебя три функции идут друг под другом, то они выравнены по началу своего имени, и если в результате рефакторинга добавилась функция с более длинным возвращаемым значением, то ты вынужден будешь сдвинуть все вышестоящие функции, чтобы сохранить форматирование. В итоге при просмотре diff у тебя получится изменений больше, чем реально было необходимо. И человек, который занимается сведением веток, я тебе клянусь, будет просто в ярости от такого.
Так что лучше отвыкать от этого пораньше.
Добавлено через 1 час 8 минут
_stanislav, кстати, его антиподом можно было бы назвать стиль коллеги _Ivana.

Пример #1

Цитата Сообщение от _Ivana Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
 
void l(int i, char c) {while (i-->0) cout<<c;}
 
int main() {
    setlocale(LC_ALL, "rus");
    char ch; int height = 0; bool q = 0;
 
    cout << "Введите символ: "; cin >> ch;
    cout << "Введите высоту треугольника: "; cin >> height;
    cout << "Заполненный или пустой? (1, 0) "; cin >> q;
    
    l(height-1, ' '); cout << ch << '\n';
    for (int i = 1; i < height-1; i++) {
        l(height-i-1,  ' '); cout << ch;
        l(2*i-1, q ? ch : ' '); cout << ch << '\n';
    }
    l(2*height-1, ch); cout << '\n';
}

Пример #2

Цитата Сообщение от _Ivana Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;
 
const int n=6;
int m[n];
 
void f(int k) {
    if (k==n) {for (int i=0; i<n; i++) cout<<m[i]<<" "; cout<<"\n";}
    for (int i=1; i<=n; i++) {
        bool c=false; for (int j=0; j<k; j++) if(m[j]==i) {c=true; break;} if (c) continue;
        m[k]=i; f(k+1);
    }
}
int main() {f(0);}


Характерные недочёты:
  • несколько операторов (statements) на одной строке
  • слепленные в кучу операции, операторы и скобки

0
Убежденный
03.10.2016, 09:01
  #11

Не по теме:


Цитата Сообщение от gru74ik Посмотреть сообщение
Если у тебя три функции идут друг под другом, то они выравнены по началу своего имени, и если в результате рефакторинга добавилась функция с более длинным возвращаемым значением, то ты вынужден будешь сдвинуть все вышестоящие функции, чтобы сохранить форматирование. В итоге при просмотре diff у тебя получится изменений больше, чем реально было необходимо.
А если у нас в компании, например, используется "умный" diff, который игнорирует
whitespace-символы и форматирование и приводит код к единому виду?

О вкусах не спорят, но вот это похоже на какой-то 'diff driven development'.
Ну давайте все растянем по вертикали, чтобы при мерже не дай бог не пришлось
править целую строчку вместо одного символа. Например, так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
for (
   int
   i
   =
   0;
   i
   <
   x;
   ++i
    )
{
    // ...
}
Ах, да, совсем забыл. У меня IntelliSense глючит, не показывая члены класса при нажатии ".", а
только "->", так что я сейчас пишу код так, чтобы обращение к классам шло строго по указателю...
:D

1
sourcerer
03.10.2016, 09:31
  #12

Не по теме:


Цитата Сообщение от Убежденный Посмотреть сообщение
А если у нас в компании, например, используется "умный" diff, который игнорирует
whitespace-символы и форматирование и приводит код к единому виду?
Тогда и говорить не о чем. Вот взял и всё сломал. Практически, наступил на горло песне :D

Добавлено через 1 минуту
Убежденный, а к чему тогда все эти ломания копий на тему оформления кода, если умный автоформаттер всё сам умеет сделать красиво?

0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
03.10.2016, 10:07 13
Цитата Сообщение от gru74ik Посмотреть сообщение
после операторов for, if else, while вставляй пробел
Никогда не понимал зачем он здесь нужен! Я, наоборот, не могу читать код, пока не поубиваю эти пробелы после for и имен функций. Думал я один так пишу, но, порывшись в книгах, обнаружил такой же стиль в книге Саттера и его совместной с Александреску.
1
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
03.10.2016, 10:15 14
Цитата Сообщение от Mr.X Посмотреть сообщение
Никогда не понимал зачем он здесь нужен!
Точно не помню где (возможно, у Прата) была такая рекомендация, чтобы отличалось от функций.
0
Эксперт С++
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
03.10.2016, 10:25 15
Цитата Сообщение от gru74ik Посмотреть сообщение
Так вот у такого форматирования зависимость символов не только горизонтальная, как обычно, но и вертикальная.
Ну, так в этом и смысл. Я тут очень согласен с Аленом Голубом, что выравнивание кода по вертикали в разы повышает его читаемость.
0
553 / 361 / 206
Регистрация: 27.11.2014
Сообщений: 1,049
03.10.2016, 10:30 16
pavlenko2k16, я не буду показывать как надо, потому что это дело личное. Чтение любого код предполагает какие-то усилия, а понедельник бывает тяжелый. Иногда человеку проще вызвериться по поводу того, что с кодом что-то не то, чем вникать в него (авось повезет и в код не придется дальше вникать). Словно для таких случаев и придуманы всякие правила и требования к коду и его оформлению (как будто одного понедельника для этого мало!) В некоторых языках программирования нет шаблонных конструкций вроде условного оператора или цикла и нет ничего кроме goto в разных формах. Но встречается goto и в СИ, когда память берегут и не спешат забивать её переменными счетчиков циклов. Иногда goto не просто бросает нить программы в очередную пропасть, но еще и контекст восстанавливает (каким он был до какого-то момента). Goto не только любимый повод начать понедельник с хорошего скандала, но и способ реализации базы данных mail.ru - Tarantool (смотрите и дивитесь goto)
1
Ушел с форума
Эксперт С++
16473 / 7436 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.10.2016, 10:41 17
Цитата Сообщение от gru74ik Посмотреть сообщение
Убежденный, а к чему тогда все эти ломания копий на тему оформления кода, если умный автоформаттер всё сам умеет сделать красиво?
Ну вообще, посыл заключался в том, что читаемость кода - главное, а угождать
особенностям поведения diff tools, IDE и т.п. - это второстепенное. IMHO.
0
Модератор
Эксперт CЭксперт С++
5284 / 2371 / 342
Регистрация: 20.02.2013
Сообщений: 5,770
Записей в блоге: 20
03.10.2016, 10:41 18
Убежденный, Mr.X, ture, ок, я понял. А возвращаясь к вопросу ТС? Насколько плохо написан его код? На что бы стоило обратить внимание чисто стилистически и концептуально?
0
192 / 128 / 52
Регистрация: 19.01.2010
Сообщений: 518
03.10.2016, 10:45 19
goto не так и плох сам по себе, тот же ассемблер без него ни куда. разница только в том, что в высокоуровневых языках гоуту можно(крайне желательно) заменять более понятными человеку конструкциями. тут вопрос только читабельности и сопровождаемости кода. имхо
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
03.10.2016, 10:55 20
Цитата Сообщение от pavlenko2k16 Посмотреть сообщение
C++
1
privetstvie:
Ну, если это приветствие, то здесь
Цитата Сообщение от pavlenko2k16 Посмотреть сообщение
C++
1
2
string second = str.substr(pos+separ.length());//должны быть секунды
string separate("::::"); //и сепаратисты


Добавлено через 1 минуту
Цитата Сообщение от pavlenko2k16 Посмотреть сообщение
C++
1
goto privetstvie;
готы приветствуют?
0
03.10.2016, 10:55
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
03.10.2016, 10:55
Помогаю со студенческими работами здесь

Правильно ли написан код
Извините, подправьте плиз, всем заранее огромное спасибо #include&lt;iostream.h&gt;...

Правильно ли написан код .cpp?
Вот сам код #define _CRT_SECURE_NO_WARNINGS #include &lt;Windows.h&gt; #include &lt;HCNetSDK.h&gt; ...

Этот код написан на С++ или Delphi?
//--------------------------------------------------------------------------- #include &lt;vcl.h&gt;...

Код написан,нужна небольшая корректировка.Массивы
Задана матрица размером N×M, N,M&lt;50. Получить массив B, присвоив его k-му элементу значение 1,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru