Сортировка строк на С++, Программирование |
nvova
профи!
Группа: Наши Люди Сообщений: 523 Регистрация: 10.01.2006 Из: СПб Пользователь №: 104.042
Респектов: 154
| Имеется структура типа "s". CODE struct s { ... char rab[30]; ... };
Сортирую строки (qsort): CODE int compare(const void *a,const void *b) { return( strcmp((*(s*)a).rab,(*(s*)b).rab) ); } Возник вопрос куда впихнуть "(char *)" или что-то вроде этого, чтоб чтоб не возникала ошибка: cannot convert parameter from char to int. Пробовал по всякому, но чего-то не выходит | |
| |
14.05.2007 - 22:05 |
Штуцер
Специалист
Группа: Наши Люди Сообщений: 363 Регистрация: 2.03.2006 Из: The Earth planet Пользователь №: 125.765
Респектов: 83
| Совершенно согласен с Яхом, одно маленькое "но": разные компиляторы содержат свои собственные библиотеки для работы со строками, поэтому можно включать CODE #include <cstring> или CODE #include <cstring.h> или CODE #include <string.h> или CODE #include <string> хоть что-то, да должно сработать. Верно, Ях? | |
| |
14.05.2007 - 22:19 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Верно, можно еще просто подключить windows.h. Тоже компилируется нормально. З.Ы. Ты первый, кто написал по-русски мой ник. Аж непривычно как-то | |
| |
2.06.2007 - 13:39 |
nvova
профи!
Группа: Наши Люди Сообщений: 523 Регистрация: 10.01.2006 Из: СПб Пользователь №: 104.042
Респектов: 154
| Курсач и др., наконец, сдал Вобщем в первом посту у меня правильно. Извиняюсь за беспокойство, ошибка была в другом. Возник еще такой вопрос: Искал информацию по блокировке файла на запись при определенных определенных операциях, но инфы куча для Линукса, а как это сделать в винде че-то не нашел. Если можно, объясните примером. | |
| |
15.11.2008 - 3:44 |
Niuk
Грамотный
Группа: Наши Люди Сообщений: 221 Регистрация: 20.04.2005 Из: Север Пользователь №: 11.753
Респектов: 11
| Всем привет, есть похожая проблема в с++ чайник полный подскажите плиз как написать функцию сортировки строк в файле. Вот пример. Code #include <fstream.h> #include <string.h> #include <conio.h> #include <iomanip.h> #include <stdlib.h> #include <io.h> #define ID 4 #define DATA 9 #define TIME 6 #define NAME 12 struct ychet { char id[ID]; char data[DATA]; char time[TIME]; char name[NAME]; };
void sort(); // Функция сортировки строк из файла с последюущей записью в файл (можно создать новый файл) и выводом на экран. { что тут писать и по возможности, как это работает? };
Пример файла для сортировки (сортировку произвести по полю id) Code 1 //id 12.10.07 //data 12-23 //time Петров //name 4 12.05.08 14-56 Иванов 2 30.11.07 15-00 Сидоров
Конечный файл Code 1 //id 12.10.07 //data 12-23 //time Петров //name 2 30.11.07 15-00 Сидоров 4 12.05.08 14-56 Иванов
| |
| |
18.11.2008 - 18:47 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Цитата | Quote(Niuk @ 15.11.2008 - 4:44) Пример файла для сортировки (сортировку произвести по полю id) А заранее известно кол-во строк в файле? | |
| |
18.11.2008 - 19:52 |
Niuk
Грамотный
Группа: Наши Люди Сообщений: 221 Регистрация: 20.04.2005 Из: Север Пользователь №: 11.753
Респектов: 11
| Цитата | Quote(yah @ 18.11.2008 - 19:47) А заранее известно кол-во строк в файле? Нет, это всеголишь одна из немногих функций из программы работы с БД То есть программа так же должна пополнять, удалять и отменять изменения в файле, Проводить поиск по заданому полю. Всё остальное реализовано кроме сортировки. Как сдам(если сдам) курсовик выложу его в ветке "учимся в месте". | |
| |
19.11.2008 - 0:38 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Цитата | Quote(Niuk @ 18.11.2008 - 20:52) struct ychet { char id[ID]; char data[DATA]; char time[TIME]; char name[NAME]; }; Цитата | Quote(Niuk @ 15.11.2008 - 4:44) Пример файла для сортировки (сортировку произвести по полю id) 1. Если я не ошибаюсь, то сортировать по массивам нельзя, отсюда следуют пункты... 2. Поле ID - точно массив? 3. ...Точно типа char? | |
| |
19.11.2008 - 2:54 |
Niuk
Грамотный
Группа: Наши Люди Сообщений: 221 Регистрация: 20.04.2005 Из: Север Пользователь №: 11.753
Респектов: 11
| Исходник полностью рабочий компилируется bc++ v3.1 В структуре ychet все поля типа чар. Сортировка нужна по выбранному полю, но для примера подойдет и первое поле id[ID] » Исходник « Code #include <fstream.h> #include <string.h> #include <conio.h> #include <iomanip.h> #include <stdlib.h> #include <io.h> #define ID 3 #define DATA 10 #define TIME 5 #define NAME 26 #define CIKL 7 #define PRIM 9 ofstream fprot; // для протокола работы программы //──────────────────────────────────────────────────────── // Описание структуры ychet //──────────────────────────────────────────────────────── struct ychet { char id[ID]; // Номер записи char data[DATA]; // Дата char time[TIME]; // Время char name[NAME]; // Наименование аппарата char cikl[CIKL]; // Циклы операций с аппаратами char prim[PRIM]; // Примечание }; //──────────────────────────────────────────────────────── // Прототипы функций //──────────────────────────────────────────────────────── void begtabl(); // Шапка таблицы void endtabl(); // Окончание таблицы void sozdanie(char); // Создание файла журнала void prosmotr(); // Просмотр записей в журнале void vibor(); // Выбор записей из журнала void del(); // Удаление записей из журнала void isprav(char); // Добавление записей в журнал //──────────────────────────────────────────────────────── // Опеpация-функция ввода в стpуктуpу с клавиатуpы //──────────────────────────────────────────────────────── istream &operator >> (istream &in, ychet &x) { int v; cout << "\n№ п-п"; in.seekg(0,ios::end); in.get(x.id,ID-1,'\n');
cout << "\nДата"; in.seekg(0,ios::end); in.get(x.data,DATA-1,'\n');
cout<<"\nВремя"; in.seekg(0,ios::end); in.get(x.time,TIME-1,'\n');
cout<<"\nДиспетчерское наименование аппарата:"; in.seekg(0,ios::end); in.get(x.name,NAME-1,'\n');
cout<<"\nЦиклы операций с аппаратами:"; in.seekg(0,ios::end); in.get(x.cikl,CIKL-1,'\n');
cout << "\nПримечание"; in.seekg(0,ios::end); in.get(x.prim,PRIM-1,'\n'); return in; } //──────────────────────────────────────────────────────── // Опеpация-функция вывода стpуктуpы на дисплей //──────────────────────────────────────────────────────── ostream &operator << (ostream &out, ychet x) { // вывод на экран out.setf(ios::left); out << "║ " << setw(ID) << x.id << " │ " << setw(DATA) << x.data << " │ " << setw(TIME) << x.time << " │ " << setw(NAME) << x.name << " │ " << setw(CIKL) << x.cikl << " │ " << setw(PRIM) << x.prim << " ║\n";
// вывод в файл с протоколом fprot.setf(ios::left); fprot << "║ " << setw(ID) << x.id << " │ " << setw(DATA) << x.data << " │ " << setw(TIME) << x.time << " │ " << setw(NAME) << x.name << " │ " << setw(CIKL) << x.cikl << " │ " << setw(PRIM) << x.prim << " ║\n"; return out; } //──────────────────────────────────────────────────────── // Опеpация-функция ввода стpуктуpы c МД //──────────────────────────────────────────────────────── ifstream &operator >> (ifstream &in, ychet &x) { in.getline(x.id,ID,'\n'); in.getline(x.data,DATA,'\n'); in.getline(x.time,TIME,'\n'); in.getline(x.name,NAME,'\n'); in.getline(x.cikl,CIKL,'\n'); in.getline(x.prim,PRIM,'\n'); return in; } //──────────────────────────────────────────────────────── // Опеpация-функция вывода стpуктуpы на МД //──────────────────────────────────────────────────────── ofstream &operator << (ofstream &out, ychet &x) { out << x.id << '\n'; out << x.data << '\n'; out << x.time << '\n'; out << x.name << '\n'; out << x.cikl << '\n'; out << x.prim << '\n'; return out; } //──────────────────────────────────────────────────────── //Тело программы //──────────────────────────────────────────────────────── void main() { char c; textbackground(BLUE); textcolor(15); fprot.open("protokol.txt"); //открытие файла для записи протокола if (!fprot) { cerr << "Не удалось открыть файл для записи протокола\n"; return; } while (1) { clrscr(); gotoxy(25,7); cout << " ╔════════════════════════════╗\n"; gotoxy(25,8); cout << " ║ ГЛАВНОЕ МЕНЮ ║\n"; gotoxy(25,9); cout << " ╠════════════════════════════╣\n"; gotoxy(25,10); cout << " ║ 1. Создание журнала ║\n"; gotoxy(25,11); cout << " ║ 2. Добавление в журнал ║\n"; gotoxy(25,12); cout << " ║ 3. Просмотр журнала ║\n"; gotoxy(25,13); cout << " ║ 4. Выборка информации ║\n"; gotoxy(25,14); cout << " ║ 5. Удаление ║\n"; gotoxy(25,16); cout << " ║ 6. Выход ║ \n"; gotoxy(25,17); cout << " ╚════════════════════════════╝\n"; gotoxy(25,19); cout << "Ваш выбор -> "; cin.seekg(0,ios::end); c = cin.get(); switch(c) { case '1': case '2': sozdanie(c); break; case '3': prosmotr(); break; case '4': vibor(); break; case '5': del(); break; case '6': fprot.close(); // закрыли файл с протоколом работы return; default: cout << "Вводите только цифры от 1 до 7" << endl; cout << "Продолжение - клавиша Enter\n"; cin.seekg(0,ios::end); cin.get(); } } } //──────────────────────────────────────────────────────── // 1, 2 - функция создания и добавления информации в файл //──────────────────────────────────────────────────────── void sozdanie(char reg) { char c; // поток ff для вывода файла ychet.txt ofstream ff; ychet s; if ( reg == '1') { // открываем файл для создания ff.open("ychet.txt", ios::binary ); fprot << "СОЗДАНИЕ НОВОГО ФАЙЛА\n\n"; } else { // открываем файл для пополнения ff.open("ychet.txt", ios::app | ios::binary ); fprot << "ДОБАВЛЕНИЕ ИНФОРМАЦИИ В ФАЙЛ\n\n"; } if (!ff) { cerr << "Не удалось открыть файл ychet.txt для записи\n"; fprot << "Не удалось открыть файла для записи\n"; return; } // Цикл записи элементов в файл do { clrscr(); if ( reg == '1') cout << "СОЗДАНИЕ НОВОГО ФАЙЛА\n\n"; else cout << "ДОБАВЛЕНИЕ ИНФОРМАЦИИ В ФАЙЛ\n\n"; cin >> s; // ввод с клавиатуpы ff << s; // вывод в файл cout<<"\nПpодолжить ввод?(Y/N или Д/H)"; cin.seekg(0,ios::end); cin.get(c); } while (c =='y' || c=='Y' || c=='д' || c=='Д'); ff.close(); // закpытие файла } //──────────────────────────────────────────────────────── // 3 - функция просмотра содержимого журнала в табличной форме //──────────────────────────────────────────────────────── void prosmotr() { ifstream finp; ychet s; // поток fi для ввода из файла ychet.txt finp.open("ychet.txt", ios::binary); if (!finp) { cerr << "Не удалось открыть файл ychet.txt для чтения\n"; fprot << "Не удалось открыть файл для чтения\n"; return; } clrscr(); gotoxy(30,1); cout<<"Просмотр информации\n"; fprot<< "\n\n\ПРОСМОТР ИНФОРМАЦИИ\n"; begtabl(); while ( !finp.eof() ) // пока не конец файла { finp >> s; // чтение из файла if ( strlen(s.id) == 0 ) break; cout << s; // вывод на дисплей } finp.close(); // закpытие файла endtabl(); cout << "Продолжение - Enter"; cin.seekg(0,ios::end); cin.get(); } //──────────────────────────────────────────────────────── // 4 - функция поиска информации по различным полям //──────────────────────────────────────────────────────── void vibor() { char c,id[ID], data[DATA], name[NAME], prim[PRIM]; int god; ifstream fi; ychet z; long l; fi.open("ychet.txt", ios::binary);
if (!fi) { cerr << "Не удалось открыть файл ychet.txt для выборки\n"; fprot << "Не удалось открыть файл для выборки\n"; return; } while (1) { clrscr(); gotoxy(25,7); cout << "╔═══════════════════════════╗\n"; gotoxy(25,8); cout << "║ ПОИСК ИНФОРМАЦИИ ║\n"; gotoxy(25,9); cout << "╠═══════════════════════════╣\n"; gotoxy(25,10); cout << "║ 1. По № п-п ║\n"; gotoxy(25,11); cout << "║ 2. По дате ║\n"; gotoxy(25,12); cout << "║ 3. По названию ║\n"; gotoxy(25,13); cout << "║ 4. По примечанию ║\n"; gotoxy(25,14); cout << "║ 5. Возврат в главное меню ║\n"; gotoxy(25,15); cout << "╚═══════════════════════════╝\n"; gotoxy(25,18); fi.seekg(0L); //,ios::beg); fi.clear( !ios::eofbit); // сброс флага достижения конца файла cout << "Ваш выбор -> "; cin.seekg(0,ios::end); cin.get(c); clrscr(); cout << "Поиск информации\n "; fprot << "\n\nПОИСК ИНФОРМАЦИИ\n "; switch(c) { case '5': return; case '1': cout << " Введите № п-п:"; cin.seekg(0,ios::end); cin.get(id,ID-1,'\n'); fprot << " № п-п:" << id << endl; break; case '2': cout << " Введите дату:"; cin.seekg(0,ios::end); cin.get(data,DATA-1,'\n'); fprot << " Дата:" << data << endl; break; case '3': cout << " Введите наименование аппарата:"; cin.seekg(0,ios::end); cin.get(name,NAME-1,'\n'); fprot << " Название:" << name << endl; break; case '4': cout << " Введите причину операции:"; cin.seekg(0,ios::end); cin.get(prim,PRIM-1,'\n'); fprot << " Причина операции:" << prim << endl; break; } begtabl(); // вывод шапки таблицы while ( fi ) { fi >> z; if ( (c=='1' && strcmp(id,z.id) == 0 ) || (c=='2' && strcmp(data,z.data) == 0 ) || (c=='3' && strcmp(name,z.name) == 0 ) || (c=='4' && strcmp(prim,z.prim)== 0) ) cout << z; // вывод на экран } endtabl(); cout << "Продолжение - клавиша Enter\n"; cin.seekg(0,ios::end); cin.get(); } } //──────────────────────────────────────────────────────── // 5 - функция удаления информации из файла //──────────────────────────────────────────────────────── void del() { ofstream fo; // вспомогательный файл ifstream fi; char c,id[ID], data[DATA], name[NAME], prim[PRIM]; int flag = 0; ychet z; long dl;
while (1) { clrscr(); gotoxy(25,7); cout << "╔═══════════════════════════╗\n"; gotoxy(25,8); cout << "║ УДАЛЕНИЕ ИНФОРМАЦИИ ║\n"; gotoxy(25,9); cout << "╠═══════════════════════════╣\n"; gotoxy(25,10); cout << "║ 1. По № п-п ║\n"; gotoxy(25,11); cout << "║ 2. По дате ║\n"; gotoxy(25,12); cout << "║ 3. По названию ║\n"; gotoxy(25,13); cout << "║ 4. По примечанию ║\n"; gotoxy(25,14); cout << "║ 5. Возврат в главное меню ║\n"; gotoxy(25,15); cout << "╚═══════════════════════════╝\n"; gotoxy(25,18); fi.seekg(0L); //,ios::beg); fi.clear( !ios::eofbit); // сброс флага достижения конца файла cout << "Ваш выбор -> "; cin.seekg(0,ios::end); cin.get(c); clrscr(); cout << "Удаление информации\n "; fprot << "\n\УДАЛЕНИЕ ИНФОРМАЦИИ\n ";
switch(c) { case '5': return; case '1': cout << " Введите № п-п:"; cin.seekg(0,ios::end); cin.get(id,ID-1,'\n'); fprot << " № п-п:" << id << endl; break; case '2': cout << " Введите дату:"; cin.seekg(0,ios::end); cin.get(data,DATA-1,'\n'); fprot << " Дата:" << data << endl; break; case '3': cout << " Введите наименование аппарата:"; cin.seekg(0,ios::end); cin.get(name,NAME-1,'\n'); fprot << " Название:" << name << endl; break; case '4': cout << " Введите причину операции:"; cin.seekg(0,ios::end); cin.get(prim,PRIM-1,'\n'); fprot << " Причина операции:" << prim << endl; break; } fi.open("ychet.txt", ios::binary ); if (!fi) { cerr << "Ошибка открытия файла для удаления информации"; fprot << "Ошибка открытия файла для удаления информации\n"; exit(1); } fi.seekg(0,ios::beg); fo.open("tmp.txt", ios::binary); if (!fo) { cerr << "Ошибка открытия файла для записи"; exit(1); } fo.seekp(0,ios::beg); while ( !fi.eof() ) { fi >> z; if (strlen(z.id) == 0 ) break; if (strcmp(z.id, id ) == 0) { flag = 1; cout << "\nИнформация удалена\n"; fprot << "Информация удалена\n"; cout << " Продолжение - Enter\n"; cin.seekg(0,ios::end); cin.get(); } else fo << z; // если информация не подлежит удалению // запись в вспомогательный файл } fi.close(); fo.close(); if (flag == 0) { cout << "Нет информации для удаления" << endl; fprot << "Нет информации для удаления" << endl; } else { remove("ychet.txt"); // удаление с диска файла ychet.txt rename("tmp.txt","ychet.txt"); // переименование файла tmp.txt в ychet.txt } return; } //──────────────────────────────────────────────────────── // вывод шапки таблицы на экран и в файл протокола //────────────────────────────────────────────────────────
} void begtabl() { // вывод на экран cout << "╔═════╤════════════╤═══════╤════════════════════════════╤═════════╤═══════════╗\n"; cout << "║ № │ Дата │ Время │ Диспетчерское │ Циклы │Примечание ║\n"; cout << "║ п-п │ │ │ наименование аппарата │аппаратов│ ║\n"; cout << "╟─────┼────────────┼───────┼────────────────────────────┼─────────┼───────────╢\n";
// вывод в файл протокол fprot << "╔═════╤════════════╤═══════╤════════════════════════════╤═════════╤═══════════╗\n"; fprot << "║ № │ Дата │ Время │ Диспетчерское │ Циклы │Примечание ║\n"; fprot << "║ п-п │ │ │ наименование аппарата │аппаратов│ ║\n"; fprot << "╟─────┼────────────┼───────┼────────────────────────────┼─────────┼───────────╢\n"; return; } //──────────────────────────────────────────────────────── // вывод окончания таблицы на экран и в файл протокола //──────────────────────────────────────────────────────── void endtabl() { // вывод на экран cout << "╚═════╧════════════╧═══════╧════════════════════════════╧═════════╧═══════════╝\n";
// вывод в файл протокола fprot <<"╚═════╧════════════╧═══════╧════════════════════════════╧═════════╧═══════════╝\n"; return; } | |
| |
19.11.2008 - 8:21 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Цитата | Quote(Niuk @ 19.11.2008 - 3:54) В структуре ychet все поля типа чар. Сортировка нужна по выбранному полю, но для примера подойдет и первое поле id[ID] Смотри, допустим даны числа 1 3 5 2. Чтобы их отсортировать (например по возрастанию), нужно их сравнить между собой... А если вместо чисел - массивы? Как тогда? Как ты определишь что, например, массив А больше массива Б ? Скорее всего поле ID должно быть простого типа (int например)... | |
| |
19.11.2008 - 12:31 |
yah
профи!
[SoftoRooMTeaM]
Группа: Наши Люди Сообщений: 2.336 Регистрация: 27.01.2006 Из: рнд Пользователь №: 500
Респектов: 408
| Принимай, только я бы на твоем месте, прежде чем использовать, все перепроверил бы раз 10 » Нажмите, для открытия спойлера | Press to open the spoiler « Code #include <iostream.h> #include <fstream> #include <string.h> #include <conio.h> #include <iomanip.h> #include <stdlib.h> #include <io.h>
using namespace std;
#define filename "d:\\1.txt" //файл из которого читаем данные #define filename2 "d:\\2.txt" //файл в который записываем данные #define ID 4 #define DATA 9 #define TIME 6 #define NAME 12
struct ychet { unsigned int id; //char ID[ID]; char data[DATA]; char time[TIME]; char name[NAME]; };
void sort(const ychet* data); //Сортировка, первый параметр - указатель на массив данных, int count; //Счетчик int lenght; //Длинна массива
int main()
{ char temp_id[11]; //максимальное значение ID из файла - до 10 цифр (можно выставить и больше) ifstream fin; //Объявляем поток для чтения из файла fin.open(filename); //Открываем дайл для чтения while(fin.ignore(20,'\n')) //Считаем кол-во строк в файле для определения общего числа блоков данных lenght++;
fin.clear(); //Обнуляем все биты состояния потока fin.seekg(0); //Возвращаемся на начало файла
ychet* data=new ychet[lenght/4]; //Выделяем память под массив для хранения блоков данных
while(fin.getline(temp_id,11)) //Пока идет ввод: { //...считываем из файла строку с ID во временную переменную... data[count].id=atoi(temp_id); //...приводим ID к числовому значению и заносим в массив... fin.getline(data[count].data,10); //...заносим в массив поле DATA из файла... fin.getline(data[count].time,7); //...TIME... fin.getline(data[count].name,13); //...NAME count++; //...увеличиваем счетчик на 1 };
fin.close(); //Закрываем поток для чтения файла sort(data); //Сортировка delete [] data; //Освобождаем память, выделенную для массива
return 0;
}
void sort(const ychet* data) { int* index=new int[count]; //Выделяем память под индексный массив... for (int a=0;a<count;a++) //...заполняем его элементами от 0 до lenght index[a]=a; int tmp; //Переменная для временного хранения значения элемента индексного массива for(int i = 0; i <= count-1; i++) //Сортировка методом "пузырька" с использованием индексного массива { for(int j = 0; j <= count-2-i; j++) { if( data[index[j]].id>data[index[j+1]].id ) { tmp = index[j]; index[j] = index[j+1]; index[j+1] = tmp; } } }
ofstream fout; //Объявляем поток для записи в файл fout.open(filename2,ios_base::out); //Открываем файл для записи for (a=0;a<count;a++) //Записываем в файл блоки данных, отсортированные по полю ID { fout<<data[index[a]].id<<endl; fout<<data[index[a]].data<<endl; fout<<data[index[a]].time<<endl; fout<<data[index[a]].name<<endl; }
delete [] index; //Освобождаем память, выделенную для индексного массива
}
| |
| |
|
|