PDA

Просмотр полной версии : Дан массив данных, как доделать программу. что бы работала



Alex.K
15.06.2009, 19:12
Дан массив данных о работающих в фирме:
фамилия, имя, отчество, адрес ( улица, дом, квартира) и дата поступления на работу (месяц, год).
Напечатать данные тех из них, кто на сегодняшний день проработал уже не менее 5 лет.
Проблемы такие:
1) пишет (Введите дату) вводишь, нажимаешь Enter, выводит сразу две строки(Введите ФИО: Введите адрес)
2) правильно ли делается сравнение?



#include <iostream>

using namespace std;
int j, g;

struct Works{
char fio[30];
char adres[30];
int year;
};

int main(){
setlocale(0,"RUS");
const int count = 3;

int data;

cout<<"Введите дату:";//дата для сравнения
cin>>data;
Works workers[count];

for (int i = 0; i < count; i++)
{
cout<<"Введите ФИО: ";
cin.getline(workers[i].fio,30);
cout<<"Введите адрес: ";
cin.getline(workers[i].adres,30);
cout<<"Введите дату трудоустройства: ";
cin>>workers[i].year;
}

for (int i = 0; i < count; i++)
{
if ((data-workers[i].year) >= 5)//сравнение
cout << "\nНе менее 5 лет проработал(а): \n"<< workers[i].fio
<< "\nАдрес: " << workers[i].adres << '\n'
<< "\nДата трудоустройства: " << workers[i].year << '\n'
<< '\n';
}
system("pause");
return 0;
}

WinMain
16.06.2009, 11:34
Это давно известная проблема. Всё дело в том, что когда ты вводишь в консоль первую строку и нажимаешь Enter, введённая строка считывается, но в буфере консоли остаётся непрочитанным символ перевода строки. Следующая команда на чтение воспринимает этот символ как уже введённую пустую строку. Поэтому не удивительно, что сразу же идёт следующий запрос ввода строки.
тебе после операции cin >> data нужно выполнить ещё одну операцию чтения, чтобы проглотить этот лишний символ.

Попробуй сделать так:
cin >> data;
cin.get();

Или так:
char c;
cin >> data;
cin >> c;

И так после каждой строки.

Airhand
16.06.2009, 11:34
Отключи оптимизация, она, бывает, делает пункт №1.
Для того, чтобы посмотреть тех, кто работает 5 лет надо из текушей даты вычитать дату поступления и потом уже сравнивать. Текущую дату надо взять, а не вычитать из нуля.

Alex.K
16.06.2009, 16:11
WinMain и Airhand спасибо за помощь.
Вот с этим вводится нормально.
cin.get();
Но только не после каждой строки, а после
cout<<"Введите дату:";
cin>>data;
и после
cin>>workers[i].year;
cin.get();
иначе только один цикл нормально,
а далее снова две строки.

Воздушная рука
(Отключи оптимизация,)-что такое оптимизация? и чтобы я оконча-
тельно на запутался-в данном случае?
(Текущую дату надо взять, а не вычитать из нуля) Но здесь же так и делается (if ((data-workers[i].year) >= 5)//сравнение).
Сначала дата вводится(data), потом данные, из данных берётся дата поступления(workers[i].year), и из(data) вычитается.
А при сравнение всё равно ошибка, выводит только 3-и данные, если 2-е данные не соответствуют условию, или 2-е и 3-и данные. если 3-и не
соответствуют условию.
О как.

Airhand
16.06.2009, 17:03
Воздушная рука Вообще-то ники не переводятся...

что такое оптимизация? и чтобы я оконча-
тельно на запутался-в данном случае? Оптимизация проводится компилятором. Так что зависит от среды разработки.
Тут не оптимизация, и, скорее-всего, WinMain прав, просто я нечасто сталкиваюсь с консолью.
Скорее всего ошибка с вводом/выводом консоли.

Romeo
16.06.2009, 17:18
Отключи оптимизация, она, бывает, делает пункт №1.
Никогда о таком не слышал. Звучит мифически. Производители компиляторы бы понесли огромные убытки, имей их детище такой баг: зачем нужен компилятор, который не генерирует нормальный код без оптимизации. Думаю, что ты с чем-то перепутал.


Текущую дату надо взять, а не вычитать из нуля.
Airhand, где ты ноль увидел? Или ты не прочитал следующие две строки после объявления переменной data? Там в эту переменную читается значение к клавиатуры. И даже если бы этого чтения не было, в переменной бы всё равно не был ноль. Там был мы мусор.

Airhand
16.06.2009, 17:37
Никогда о таком не слышал. Звучит мифически. Производители компиляторы бы понесли огромные убытки, имей их детище такой баг: зачем нужен компилятор, который не генерирует нормальный код без оптимизации. Думаю, что ты с чем-то перепутал.

Раз не слышал, значит мало программил. Не знаю как где, а Borland и мелкософт грешат этим, поэтому в Builder-e и VS оптимизацию отключают.



Airhand, где ты ноль увидел? Или ты не прочитал следующие две строки после объявления переменной data? Там в эту переменную читается значение к клавиатуры. И даже если бы этого чтения не было, в переменной бы всё равно не был ноль. Там был мы мусор.
Что б ты знал, по 3 стандарту все встроенные типы всегда инициализируются нулём в той или иной форме.

Romeo
16.06.2009, 18:00
Раз не слышал, значит мало программил.
Не буду отвечать на провокацию, Airhand. Ты свой уровень уже показал в другой теме.

Не знаю как где, а Borland и мелкософт грешат этим, поэтому в Builder-e и VS оптимизацию отключают.

Продукт, являющийся частью поставки Oracle - достаточно серьёзный пример? Громадный комплекс, установленный в бОльшей части лабораторий и клиник в штатах достаточно серьёзный пример? Над первых продуктом я проработал 4 года, над вторым уже 2. Оптимизация включена по самые помидоры. Где это видано, чтобы официальная feature компилятора отключалась? Зачем такой компилятор вообще нужен? Не знаю на счёт Builder, но оптимизацию в VS отключают не те люди, который мало "программили", а те, которым лень разобраться в сути проблемы.


Что б ты знал, по 3 стандарту все встроенные типы всегда инициализируются нулём в той или иной форме.
Чтоб ты знал, согласно стандарта ANSI ISO 97, инициализация нулём касается только глобальных и статических данных, но не касается локальных переменных. Если этот простой факт не знаешь, да ещё и под рукой нет стандарта, то хоть бы на VS проверил перед тем, как писать.

ОК, ладно, этого ты не знаешь. Но мы сейчас совсем о другом. Даные там читаются из стандартного потока, никакого неинициализированного значения там нет. Снова читаешь невнимательно?

Airhand
17.06.2009, 12:50
Не буду отвечать на провокацию, Airhand. Ты свой уровень уже показал в другой теме.
Это, далее, идёт не ответ. Это так себе. :)



Продукт, являющийся частью поставки Oracle - достаточно серьёзный пример? Громадный комплекс, установленный в бОльшей части лабораторий и клиник в штатах достаточно серьёзный пример? Над первых продуктом я проработал 4 года, над вторым уже 2. Оптимизация включена по самые помидоры. Где это видано, чтобы официальная feature компилятора отключалась? Зачем такой компилятор вообще нужен? Не знаю на счёт Builder, но оптимизацию в VS отключают не те люди, который мало "программили", а те, которым лень разобраться в сути проблемы.

Borland пишет на borland-e. В VS пишут такие софтварные гиганты как мелкософт, ISD и другие. И все они отклчают оптимизацию потаму, что ленивые. :D



Снова читаешь невнимательно? Может я невнимательно читал код.

Alex.K
17.06.2009, 14:29
Я вас понял.
Таки как доделать программу?

Airhand
17.06.2009, 19:34
А что, как говорил WinMain не получается ?

Alex.K
18.06.2009, 12:09
1) исправилось, вводится нормально.
А выводом проблеммы.
А при сравнение всё равно ошибка, выводит только 3-и данные, если 2-е данные не соответствуют условию, или 2-е и 3-и данные. если 3-и не
соответствуют условию.
Ерунду выводит.

Airhand
18.06.2009, 12:57
1. Где программишь, в какой среде ? Если в Bulder или VS, то попробуй отключить оптимизацию. Похоже оно слепило 2 цикла в один.
2. Попробуй выводить std::endl вместо "\n".
3. Попробуй заменить одинарные кавычки двойными.
4. После условия в if, поставь "{", а в конце оператора вывода - "}".

Romeo
18.06.2009, 13:46
ISD
Я был уверен, что ты знаешь ISD, если ты из Днепропетровска :) Так вот, я работаю именно в ISD :) Оптимизация в SoftLabMic врублена по максимуму как на Win в студии, так и на AIX серверах.

Я повторюсь, но оно того стоит. Оптимизация в компиляторе, это чуть-ли не одна из его основных фич. Если эта фича работает некорректно, то от такого компилятора отказываются, либо, если виноваты люди, которые написали кривой код, то код нужно переписывать, а людей, если они продолжают выдавать на гора код с запашком, то увольнять следует таких людей, да и всё. Сборка проекта, сделанная без оптимизации никому не нужна. Сборка без оптимизации - первый признак профессиональной непригодности команды.

Airhand
18.06.2009, 14:05
Я был уверен, что ты знаешь ISD, если ты из Днепропетровска :) Так вот, я работаю именно в ISD :) Оптимизация в SoftLabMic врублена по максимуму как на Win в студии, так и на AIX серверах.
Я знаю ISD, но не работал там. У нас, в городе, на тех проектах, что я знаю, оптимизация вырублена. Не знаю как у вас, в Крыму.


Я повторюсь, но оно того стоит. Оптимизация в компиляторе, это чуть-ли не одна из его основных фич. Если эта фича работает некорректно, то от такого компилятора отказываются, либо, если виноваты люди, которые написали кривой код, то код нужно переписывать, а людей, если они продолжают выдавать на гора код с запашком, то увольнять следует таких людей, да и всё. Сборка проекта, сделанная без оптимизации никому не нужна. Сборка без оптимизации - первый признак профессиональной непригодности команды.
Одна из фич оптимизации: раскрытие циклов. Как прикажеш её делать в том примере ?

Romeo
18.06.2009, 14:48
Короче, ладно, хватит флудить. Я наконец-то нашёл время, чтобы разобрать код. Естественно оптимизация здесь не при чём, а виноваты, как обычно, кривые руки программиста :)

При работе с потоками STL есть известная рекомендация не смешивать чтение строк через оператор >> и с помощью функции getline. Следует использовать либо только одно, либо только другое. Всё дело в том, что оператор >> прячет от пользователя все переводы кареток, расценивая их, как управляющие символы, то есть он завершает ввод строки, когда встречает перевод каретки. Функция getline тоже читает до перевода каретки (либо до другого делиметра, но в нашем коде дилиметр не указан, значит подразумевается дилиметр '\n'). То есть вроде оба способа учитывают перевод каретки и но вот только дейтсвуют они по разному. Оператор >> при достижении '\n' возвращается, оставляя '\n' в потоке, а getline возвращается, удаляя '\n'. Таким образом, если вызвать сначала оператор >>, то следующий за ним вызов getline проскочит за счёт того, что он увидит первым символом в потоке символ '\n', который был оставлен там оператором, и тут же выйдет, вернув пустую строку.

Самый правильный фикс - перейти целиком на использование оператора >>.

Можно также рассмотреть менее кардинальный способ, который предложил WinMain, то есть после КАЖДОГО вызова оператора >>, насильно забирать из потока перевод каретки. Alex.K, обрати внимание на слово, которое я написал большими буквами. Скорее всего ты сделал забор каретки из потока только в одном месте, в то время, как у тебя в программе встречается два места, где вызывается оператор >>.

Вот работающий код:


#include <iostream>

using namespace std;
int j, g;

struct Works{
char fio[30];
char adres[30];
int year;
};

int main(){
setlocale(0,"RUS");
const int count = 3;

int data;
char temp[2];

cout<<"Введите дату:";//дата для сравнения
cin>>data;
cin.getline(temp, 2);
Works workers[count];

for (int i = 0; i < count; i++)
{
cout<<"Введите ФИО: ";
cin.getline(workers[i].fio,30);
cout<<"Введите адрес: ";
cin.getline(workers[i].adres,30);
cout<<"Введите дату трудоустройства: ";
cin>>workers[i].year;
cin.getline(temp, 2);
}

for (int i = 0; i < count; i++)
{
if ((data-workers[i].year) >= 5)//сравнение
cout << "\nНе менее 5 лет проработал(а): \n"<< workers[i].fio
<< "\nАдрес: " << workers[i].adres << '\n'
<< "\nДата трудоустройства: " << workers[i].year << '\n'
<< '\n';
}
system("pause");
return 0;
}


Сравнение у тебя написано верно и работает оно также верно, я проверил у себя. Если не работает, то давай конкретный пример данных, на которых это видно. Будем разбирать.


Я знаю ISD, но не работал там. У нас, в городе, на тех проектах, что я знаю, оптимизация вырублена. Не знаю как у вас, в Крыму.
Я работаю в Севастополе над теми же проектами, над которыми люди работают в Днепропетровске. У нас нет отдельного проекта. Если говоришь, что знаешь проекты, в которых оптимизация отключена, то название проектов, плиз, в студию. Прямо сейчас зайду и посмотрю в настройках и в билд скриптах.


Одна из фич оптимизации: раскрытие циклов. Как прикажеш её делать в том примере ?
Одна из фич оптимизации - её интеллектуальность. Оптимизация делается в нужном месте в нужное время. Если она не может быть применена, то она не делается.

Если у тебя есть сомнения, что оптимизацию тут вообще можно применить, то почему говоришь, что в оптимизации дело? Ведь если её нельзя применить, то её здесь нет :) (это вопрос чисто о логике, есть здесь оптимизация на самом деле или нет, это вопрос отдельный)

Alex.K
18.06.2009, 22:08
Среда Microsoft Visual C++ 2008 Express Edition.
отключить оптимизацию
Отлючать JIT-оптимизацию при загрузке модуля(только управляемый код).галочка стоит.
Ещё есть оптимизация кода в Конструкторе Windows Forms там true .
Но это помоему другое
Какую?

Romeo.
Скопировал ваш код.
Ввожу.
дата 062009
ФИО F
адрес ulf
Дата труд. 122001.
далее соот.
i
uli
062003
o
ulo
052008

Выводит 2-е и 3-и данные.
Предложения Airhand проверил,
Набираю как и для вашего кода,
выводит тоже самое.

azrael
19.06.2009, 12:43
выводит тоже самое.
А вы возьмите калькулятор и посчитайте на нем разницу между введенными вами датами. По-моему, результат вполне ожидаем. Либо разделите месяц и год, либо при вычислении разности учитывайте, чем месяц отличается от года. Вы просто находите разность двух целых чисел, и нигде не сказано, что это дата.

Ваше сравнение будет работать корректно только в том случае, если месяц поступления на работу такой же, как и в data.

Airhand
19.06.2009, 13:32
Я работаю в Севастополе над теми же проектами, над которыми люди работают в Днепропетровске. У нас нет отдельного проекта. Если говоришь, что знаешь проекты, в которых оптимизация отключена, то название проектов, плиз, в студию. Прямо сейчас зайду и посмотрю в настройках и в билд скриптах.
Вообще говоря, это неверно. В ISD много тим, и если вы работаете в разных странах или городах над теми же проектами, это ещё не значит, что в одной тиме.



Одна из фич оптимизации - её интеллектуальность. Оптимизация делается в нужном месте в нужное время. Если она не может быть применена, то она не делается.

Если у тебя есть сомнения, что оптимизацию тут вообще можно применить, то почему говоришь, что в оптимизации дело? Ведь если её нельзя применить, то её здесь нет :) (это вопрос чисто о логике, есть здесь оптимизация на самом деле или нет, это вопрос отдельный) Покажи где я говорил, что дело в оптимизации. Я говорил, что она МОЖЕТ давать такой результат. Остальное твои фантазии.


Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)


Классная логика, точнее её отсутствие: говоришь без пробелов, а те что между скобкой и "code", скобкой и "cpp" не считаются ?

Romeo
19.06.2009, 15:39
Alex.K, ну так а кто будет рассказывать в каком ты формате хочешь дату иметь? Мы сами не можем догадаться. В коде у тебя вообще написанно year, то есть год. Я туда и вводил просто год и у меня всё работало.

Если хочешь, чтобы число, которое ты ввёл расценивалось не как число, а как некая сложная конструкция, то ты сам должен обеспечить правильное сравнение для чисел подобного рода. Например, если формат у тебя должен быть таким: mmyyyy (две цифры под месяц и четыре под год), то месяц ты можешь получить по формуле date / 1000, а год по формуле date % 1000. Далее делаешь те проверки, которые тебе нужны.


Вообще говоря, это неверно. В ISD много тим, и если вы работаете в разных странах или городах над теми же проектами, это ещё не значит, что в одной тиме.
Не надо мне рассказывать об устройстве мой фирмы, я лучше его знаю. Я попросил указать название продукта, в котором оптимизация отключена, для того, чтобы я это проверил. В продукте, над которым работает моя тима - это не так. Я могу проверить любой продукт, не только свой, лишь скажи его название.


Классная логика, точнее её отсутствие: говоришь без пробелов, а те что между скобкой и "code", скобкой и "cpp" не считаются ?
Для недалёких людей естественно логика отсутствует :)

Те же, кто умеют размышлять, сразу должны понять почему я так написал. Всё очень просто. Если бы я написал тэги без пробелов, то они бы были съедены движком форума и пользователи бы увидели лишь отформатированный текст. Для того, чтобы движок не съел тэги и все могли увидеть как правильно эти тэги писать, я поместил в них пробелы, а в конце сообщения указал, что пробелы, на самом деле должны быть удалены. Неужели это не понятно?

Alex.K
19.06.2009, 20:21
Romeo спасибо за ответ.
Только растолкуйте, как это сделать.
Модифицировать year и data, если да, то как?:confused:

Romeo
19.06.2009, 21:53
Ну смотри, у тебя есть два числа, например 121990 и 112005. Задача вычислить сколько целых лет прошло от первой даты до второй, при условии, что в каждом числе первые две цифры обозначают месяц, а следующие 4 цифры - год.

Для каждого числа нужно посчитать два значения. Обозначим число за d, а месяц и год за m и y соответственно. Тогда имеем следующие соотношения:

m = d / 10000;
y = d % 10000;

Следующий шаг - вычисление разницы полных лет. Для этого нужно рассмотреть разницу лет из второго числа и первого числа:

diff = y2 - y1 = 2005 - 1990 = 15 лет.

Затем нужно проверить у какой даты номер месяца больше. Если у второй даты номер больше или равен, то всё хорошо. Если же у второй даты номер меньше, чем у первой, то разницу лет нужно уменьшить на 1, так как последний год получается неполным.

В нашем случае (m2 = 11) < (m1 = 12), следовательно diff = diff - 1 = 14 лет.

Это и есть наш ответ. После этого diff, согласно заданию, нужно сравнить с числом 5. Вот и вся премудрость.

Я написал всё словами, а не предоставил готовую программу для того, чтобы ты попробовал реализовать алгоритм сам. Удачи.

somewhere
20.06.2009, 00:57
m = d / 1000;
y = d % 1000;
Не 1000, а 10000.

Romeo
20.06.2009, 09:52
Всё, верно, в глазах рябит от нулей, потому недосчитался одним :)

Исправил прямо в сообщении. Также исправил строку (m1 = 11) на (m1 =12). Это тоже опечатка была.

Airhand
20.06.2009, 12:45
Для недалёких людей естественно логика отсутствует :) Это, наверное, учителя так учат: называть людей недалёкими...

Alex.K
20.06.2009, 18:43
Romeo спасибо за ответ и огромное спасибо за науку.
Всем также спасибо за помощь.
Всё доделал, всё работает.
Вот работающий код:



#include <iostream>

using namespace std;
int m, y, diff;

struct Works{
char fio[30]; //ФИО
char adres[30]; //Адрес
int year; //Год
int m; //Месяц
};

int main(){
setlocale(0,"RUS");
const int count = 3;
char temp[2];

cout<<"Введите месяц:";//дата для сравнения
cin>>m;
cin.getline(temp, 2);
m=m/10000;
cout<<"Введите год:";//дата для сравнения
cin>>y;
cin.getline(temp, 2);
y=y%10000;

Works workers[count];

for (int i = 0; i < count; i++)
{
cout<<"Введите ФИО: ";
cin.getline(workers[i].fio,30);
cout<<"Введите адрес: ";
cin.getline(workers[i].adres,30);
cout<<"Введите месяц трудоустройства: ";
cin>>workers[i].m;
cin.getline(temp, 2);
cout<<"Введите год трудоустройства: ";
cin>>workers[i].year;
cin.getline(temp, 2);
}
for (int i = 0; i < count; i++)
{
diff=(y-(workers[i].year%10000));
if ((workers[i].m/10000)>(m))
diff=diff-1;
{
if (diff >= 5)//сравнение
cout << "\nНе менее 5 лет проработал(а): \n"<< workers[i].fio
<< "\nАдрес: " << workers[i].adres << '\n'
<< "\nМесяц трудоустройства: " << workers[i].m << '\n'
<< "\nГод трудоустройства: " << workers[i].year << '\n'
<< '\n';
}
}
system("pause");
return 0;
}


:)


/ 10000;
% 10000
А что такое эти 10000?

Romeo
21.06.2009, 15:12
Alex.K, деление на 10000 и вычисление остатка от деления на 10000 нужно было для того, чтобы из числа типа 122009 извлечь месяц и год, то есть 12 и 2009.

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



diff = y2 - y1;
if (m2 < m1) --diff;



Это, наверное, учителя так учат: называть людей недалёкими..
Относись к людям так, как ты хочешь, чтобы они относились к тебе. Ты мне нагрубил, обвинив в отсутствии логики, я тебе ответил тем же.

Ты название продукта мне скажешь или нет?

Alex.K
21.06.2009, 17:20
Romeo спасибо.
Понял, переделаю позже.

Airhand
21.06.2009, 18:35
Относись к людям так, как ты хочешь, чтобы они относились к тебе. Ты мне нагрубил, обвинив в отсутствии логики, я тебе ответил тем же.
А что нельзя написать так [соde=срр], чтобы движок форума не прохавал ? Например, вот так: [соde=cpp]Код[соde].

Romeo
22.06.2009, 10:08
Да, можно, я даже думал над этим. Проблема здесь в том, что многие люди, прочитав подсказку в моей подписи копируют тэг через clipboard и вставляют в своё сообщение. Сам понимаешь, что русские буквы 'с' и 'о' сыграют в этом случае с ними злую шутку :)

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