генератор пароль + система "аккаунтов" ...
1. Система "аккаунтов". То есть регистрация (администратора регестрировать не надо, только пользователи) и доступ к личному "кабинету" путем ввода логина и пароля.
2. Генерация пароля. Учитель поставил задачу - сделать так, чтобы пароль для аккаунта при регистрации выдавался автоматически, соответчтвенно хотелось бы сделать что-нибудь хорошее, на эту тему.
Программу буду писать на с++ под дос, чтобы особо не гемороиться с win32 приложением ибо пока только начал это дело изучать.
У кого есть какие то соображения на эту тему - было бы неплохо их услышать....
Спасибо за внимание -)
ну вот, как бы, в общих чертах твоя игрушечная система защиты.
зы: гуглить "гаммирование", "хеширование", "рандомизатор с++".
Как я буду реализовывать саму базу данных:
у меня есть класс книга (автор, название, кол-во стр. и тд)
класс польхователей(имя, пароль)
Соответственно нужно сделать список книг чтобы например загружать его из файла, добавлять администратором новые книги, удалять и тд. Я хотел реализовать это с помощью контейнера какого-нибудь. Наприме set . Но так и не понял как.
Соответственно второй раз использовать контейнер, для того чтобы каждому польхователю соответствовало n-ое кол-во книг ....
Сейчас попробую вкратце описать проблему:
имеется
{
private:
bk_id_t id;
bk_author_t author;
pchar_t title;
bk_pgs_t pages;
public:
book(bk_author_t _author, csz_t _title, bk_pgs_t _pages);
bk_id_t get_id() const
{
return id;
}
friend bool operator == (book& bk1, book& bk2);
friend bool operator < (const book& bk1, const book& bk2);
friend std::ostream& operator << (std::ostream& stream, book& book_);
};
{
unsigned short size_st1(str_len(st1)),size_st2(str_len(st2));
unsigned short i(0),imax((size_st1<size_st2)?(size_st1):(size_st2));
while(i<imax)
{
if(st1>st2)
return 1;
else
if(st1<st2)
return -1;
else
i++;
}
return 0;
}
...
bool operator < (const book& bk1, const book& bk2)
{
if(str_compare(bk1.get_id(), bk2.get_id())>0)
return true;
else
return false;
}
book bk1("ALina", "Kniga Pizdec!", 1030);
book bk2("ALina", "Kniga Pizdec!", 1000);
book bk3("Alesha", "Kniga Molodec!", 2500);
book bk4("Petya", "Kniga Molodec!", 2500);
book_base.insert(bk1);
std::cout<<*(book_base.begin());
system("pause");
book_base.insert(bk3);
std::cout<<*(book_base.end());
Вылетает при попытке добавить вторую книгу. Причём компилится нормально.
Ну хотя бы sqlite...
std::cout<<*(book_base.end());
Вылетает при попытке добавить вторую книгу. Причём компилится нормально.
Насколько я понимаю, вылетает не при добавлении второй книги, а при разыменовании индексатора, указывающего ЗА конец контейнера. Ведь end() указывает не на последний элемент, а ЗА него.
Вот так, вроде, будет последний элемент:
Конечно, это лишь пример (причём глупый).
Добавьте все книги в множество, и просмотрите их список:
cout << *iter;
По поводу реально СУБД использование запрещено. Ибо это обучающая программа на курс программирования (и метрологии) следовательно они типа смотрят как я сам это всё дело понимаю и реализую...
По поводу
Вот так, вроде, будет последний элемент
...
Нет вылетает именно при добавлении. Причем пишет типа invalid operator < ...
то есть напрмиер у меня есть вектор из книг и я прям по одной книге хочу в файл закидать а потом n книг (n = размер файла / sizeof(book)) прочитать оттуда, при этом чтоб файл был не строкой а именно бинарный ...
открыть закрыть я полагаю надо типа
А вот как кинуть в файл сам обьект ....
А вот как кинуть в файл сам обьект ....
перегрузить оператор << и >>.
парень, ты задаешь кучу элементарных вопросов, ответы на которые есть почти в любой книге по крестам и гугле. я конечно понимаю, что конец семестра, ты в панике, как оказалось набор пивных крышек для зачета не катируется, но тупо постить на форум элементарные вопросы... ты убиваешь свое время, поверь мне, гораздо быстрее открыть книгу и прочесть, чем писать сюда, потом еще ждать когда совершенно не знакомый человек прочтет твой пост, пока ответит. за это время ты бы мог уже пол своей работы написать.
"Лучше б он пил и курил..."(с) Сплин
Зачем городить кривой трехколесный велосипед, если можно воспользоваться готовым, удобным и проверенным решением?
(Вопрос из праздного любопытства, я конечно же не отговариваю никого от бессмысленного творчества).
Да, для своего типа данных нужно определить свой operator <.
Я так понимаю, у вас задание не использовать ничего стандартного, создать всё своё? Вон и типы данных свои, и функции определения длины строки, насколько я могу судить по названиям.
Не имея понятия о ваших типах данных, набросал пример, заменив их на стандартные.
#include<iomanip>
#include<string>
#include<set>
using namespace std;
class book
{
private:
int id;
string author;
string title;
int pages;
public:
book(int _id, string _author, string _title, int _pages);
int get_id() const
{
return id;
}
friend bool operator < (const book& bk1, const book& bk2);
friend ostream& operator << (ostream& stream, book& book_);
};
book::book(int _id, string _author, string _title, int _pages):
id(_id), author(_author), title(_title), pages(_pages)
{
}
bool operator < (const book& bk1, const book& bk2)
{
return bk1.author + bk1.title < bk2.author + bk2.title;
}
ostream& operator << (ostream& stream, book& book_)
{
stream << left << setw(4) << book_.id;
stream << book_.author << " '" << book_.title << "' " << book_.pages << endl;
return stream;
}
void main()
{
set<book> book_base;
int id = 0;
book_base.insert( book(id++, "ALina", "Kniga Pizdec!", 1030) );
book_base.insert( book(id++, "ALina", "Kniga Pizdec!", 1000) );
book_base.insert( book(id++, "Alesha", "Kniga Molodec!", 2500) );
book_base.insert( book(id++, "Petya", "Kniga Molodec!", 2500) );
for (set<book>::iterator iter = book_base.begin(); iter != book_base.end(); iter++)
cout << *iter;
}
В данном примере одинаковыми считаются книги с одинаковыми авторами и названиями: за это отвечает условие bk1.author + bk1.title < bk2.author + bk2.title
Насчёт чтения/записи в файл. Не совсем ясно, что вы хотите: иметь возможность перезаписать любую книгу, не трогая остальной файл? Нет, так не получится, ведь размер данных о книге не фиксирован строго. Надо читать все данные из файла, удалять ненужные книги, добавлять новые, и по-новому записывать в файл.
Зачем городить кривой трехколесный велосипед, если можно воспользоваться готовым, удобным и проверенным решением?
(Вопрос из праздного любопытства, я конечно же не отговариваю никого от бессмысленного творчества).
твои генияльные и простые мысли мешают самоудовлетворятся топикстартеру - оттого безжалостно отбрасываются.
Кроме того, возможно у него задание - создать аналог БД - для изучения STL задача вполне. Помимо этого, я подозреваю, что ихний препАдователь вероятно прочел не так давно книжку одного афтора :) уж очень интересно похоже сформулирована задача.
По поводу препода - его (а точнее её) задача научить нас понимать что мы делаем, а не чтоб тупо пользовались готовым. Да и просто я люблю всё делать через жопу, можно было ограничиться простым массивом book[1000], врядли этого было бы мало для учебных целей, вопрос в рациональности.... Про реальную БД тпиа sqllite я уже отвечал, что это курсовая такая "написать базу данных" за нее оценку поставят, чтож мне поставят если я скажу вот вам sql ставьте мне "отлично". ДА и самоудовлетвориться хочу, надеюсь в будущем хоть чуть чтуь по специальности поработать ...
А не STL в качестве SQL, а SQL в качестве STL. :)
Я уже говорил, что задача написать БД. Насколько я знаю (может ошибаюсь) sql это язык запросов к какой-то БД и 1. я не знаю этого языка. 2. в рамках данной задачи обращаться любым языком к любой другой базе нельзя, то есть пиши свою и точка (.)
Спасибо всем кто помогает =)
а зачем? тут такого г... эм тварения уже и так хватает! %) 0_o :D
чтоб каждое поле на отдельную строку клалось или чтоб все поля в 1 строку ?
Записать книгу в файл не проблема и так и так, а вот считать из файла - проблема ... особенно со строками (название или автор, если там пробелы есть) ...
Avtor 1
Title 1
540
1
Avtor 1 & Avtor 5
Title 2
1440
...
Когда я считал первую строку : stream>>book.id;
начинаю считывать вторую std::getline(stream, book.author, '\n'); и она не считывается.
Видимо из за того, что после считывания id остается символ конца стркои в потоке, и когда начинаю считывать автора, сразу считывается тот '\n' и всё ... как это исправить ?
Записываю в файл я вот так вот :
{
stream<<book_.get_id()<<std::endl;
stream<<book_.get_author()<<std::endl;
stream<<book_.get_title()<<std::endl;
stream<<book_.get_pages()<<std::endl;
return stream;
}
Кстати есть задумка позволить в файл добавлять комментарии. Например если в строке первые два символа "//" то строку игнорировать и переходить к следущей...
Считываю я вот так вот :
{
stream>>_book.get_id();
stream>>_book.get_author();
stream>>_book.get_title();
stream>>_book.get_pages();
return stream;
}
Проблема в том что если автор или название содержат пробелы (то етсь несколько слов) то считывается только первое...
Проблема в том что если автор или название содержат пробелы (то етсь несколько слов) то считывается только первое...
std::getline
интересные у тебя функции get_* и возвращают, и устанавливают значение, интересненько...
{
const unsigned char max=40;
char buf[max];
stream>>_book.get_id();
stream.ignore(5, '\n');
stream.getline(buf, max, '\n');
_book.get_author()=buf;
stream.getline(buf, max,'\n');
_book.get_title()=buf;
stream>>_book.get_pages();
return stream;
}
Работает правильно, но код мне не нарвится, как то слишком всё не тру =) Но пока мои мозги не до чего лучшего не доходят.
Кстати, так что же лучше использовать для базы книг vector или set ? я сейчас пробую set сделать .
Функции типа get_ просто возвращают private член по ссылке, это конечно не очень тру с точки зрения сохранности данных, но так проще обращаться извне класса.
То есть можно сделать оператор дружественный к классу и он будет видеть его приват поля без всяких паблик функций ?
То есть можно сделать оператор дружественный к классу и он будет видеть его приват поля без всяких паблик функций ?
совершенно верно, а мего функции гет верни в нормально положение.
{
const unsigned char max=40;
char buf[max];
stream>>_book.get_id();
stream.ignore(5, '\n');
stream.getline(buf, max, '\n');
_book.get_author()=buf;
stream.getline(buf, max,'\n');
_book.get_title()=buf;
stream>>_book.get_pages();
return stream;
}
Работает правильно, но код мне не нарвится, как то слишком всё не тру =) Но пока мои мозги не до чего лучшего не доходят.
Не тру. Green сказал же - использовать std::getline, а не метод потока.
{
stream >> book_.id;
stream.ignore();
getline(stream, book_.author);
getline(stream, book_.title);
stream >> book_.pages;
//stream.ignore();
return stream;
}
Записываю примерно так :
{
stream<<ur.get_name()<<endl;
return stream;
}
ifstream& operator >> (ifstream& stream, user& ur)
{
stream>>ur.get_name();
return stream;
}
Есть класс man с полем private name. От него унаследован класс user. В man функция string get_name() {return name} соответственно нужно ли строку (name) возвращать по ссылке, потому что считывает не правильно =(
Есть класс man с полем private name. От него унаследован класс user. В man функция string get_name() {return name} соответственно нужно ли строку (name) возвращать по ссылке, потому что считывает не правильно =(
ну во первых, поле имени надо сделать защищенным, а не приватным. тогда оно будет доступно в классе потомке. во вторых, можно в перегруженном операторе для класса пользователей читать только те данные которых нет в классе человека, а потом вызывать оператор ввода вывода для класса человека. это будет гораздо правильней, ну если конечно базовый класс не чисто виртуальный! в третьих, функции гет возвращают значения, а не изменяют его, логически это не правильно, так что оставь их в покое. в четвертых, иди почитай книжки хорошенько, все твои проблемы возникают из за обрывочности знаний.
в файле с main() прописано setlocale(LC_ALL, "Russian"); но с русским вводом выводом констант пробелм нет а вот именно когда записываю в стринг то получается лажа ...
P.s: Проблемка с чтением записью в текстовый файл. Суть такая, есть программа, которая делает список студентов (курсовая короче), соответственно поля в классе такие:
char* surname; // фамилия
char* name; // имя
int growth; // рост
int weight; // вес
int id; // ключевое поле
static int num;
Запсь в файл я произвожу вот так вот :
ofstream file_;
file_.open("save");
file_<<ob2;
file_.close();
cout<<"Запись прошла успешна."<<endl;
...
ofstream& operator << (ofstream &stream, stud &ob)
{
stream<<ob.id<<'\n';
stream<<ob.surname<<'\n';
stream<<ob.name<<'\n';
stream<<ob.growth<<'\n';
stream<<ob.weight<<'\n';
stream<<ob.kurs<<'\n';
stream<<ob.year<<'\n';
return stream;
}
Потом читаю (вот тут вот проблема):
ifstream _file;
_file.open("save");
_file>>ob2;
_file.close();
cout<<"Чтение прошла успешна."<<endl;
...
ifstream& operator >> (ifstream &stream, stud &ob)
{
stream>>ob.id;
if(ob.id > ob.num)
ob.num = ob.id;
stream.ignore(50, '\n');
stream.getline(ob.surname, 20, '\n');
stream.getline(ob.name, 20, '\n');
stream>>ob.growth;
stream>>ob.weight;
stream>>ob.kurs;
stream>>ob.year;
stream.ignore();
return stream;
}
Читаю и записываю я список . То есть вот таким вот образом :
ofstream& operator << (ofstream &stream, spisok &sp)
{
stud* pt(sp.head);
while(pt)
{
stream<<*pt;
pt=pt->get_next();
}
return stream;
}
А вот при чтении и добавлении он считывает лишнего студента, причем пустого, то есть у меня в файле 2 студента, он считывает третьего у которого откуда то берется ID, а всё останое по нулям и пустые строк ""
ifstream& operator >> (ifstream &stream, spisok &sp)
{
stud* ob;
while(stream)
{
ob = new stud;
stream>>*ob;
if(!sp.head)
sp.head=ob;
else
{
sp.head->set_prev(ob);
ob->set_next(sp.head);
sp.head=ob;
}
}
return stream;
}
В файл записывается примерно вот так (кстати, возможно проблема с позицией в файле, потому что если после последнего записанного символа удалить невидимый '\n' чтоб курсор стоял прям после числа, и сохранить, то потом прочитается идеально):
saprikina
alina
170
70
2
5
4
abazova
ada
160
50
2
5
int main()
{
setlocale(LC_ALL, "");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
std::wcout<<L"Русский текст"<<endl;
std::wstring str;
std::wcin>>str;
std::wcout<<str<<endl;
return 0;
}
При том что шрифт в консоле НЕ точечный ...
#include<iostream>
#include<string>
using namespace std;
int main()
{
wcout.imbue(locale("rus_rus.866"));
wcin.imbue(locale("rus_rus.866"));
wcout << L"Русский текст" << endl;
wstring str;
wcin >> str;
wcout << str << endl;
return 0;
}
Кто вам сказал, что применение wstring и wchar_t автоматически означает юникод? Посмотрите, что стоит в настройках вашего проекта - Character Set: Use Unicode Character Set или Use Multi-Byte Character Set. Хотя приведённый способ работает и так, и так.
P.S. Что-то вы мечетесь туда-сюда. То set хотите использовать, то vector, для строк то string, то char*, то wstring...