Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.04.2008, 17:57   #1
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию C++, работа с потоками

Юзер вводит табельный номер рабочего, его фамилию, номер цеха и среднюю зарплату,это все сохраняется в отдельный binary-файл. Функции меню: добавлять n-записей, выводить одну запись в виде строки таблицы, выводить записи в виде таблицы, помечать на удаление или снимать пометки с указанных записей и удалять помеченные записи!

Немогу разораться как делать пометки на удаление и удалять записи!

По функциям Read и Write: препод сказал, что их нужно формить как боработку исключений(try, throw, catch). У меня только в функции Read, в файле, где находится сама функция есть закомментированный фрагмент, но он не работает!

Еще одна проблема возникла при рисовании таблицы: когда вся таблица отрисовывается, то в конце выводиться сообщение об ошибке, после которого нажимаешь любую клавишу, программа "выпригивает". Не сердитесь на меня дорогие умелые программеры! Наверное нужно передать в функцию, риусующую таблицу, количетсов записей, но не смог посчитать количество записей! Помогите с этим тоже!

Скажу большое спасибо тому, кто поможет мне!
P. S. что-то у меня не грузиться rar-архив с приложением! Из--за чего это происходит?
Вот ссылка на прогу: http://depositfiles.com/files/4997584
mat90x вне форума Ответить с цитированием
Старый 03.05.2008, 01:28   #2
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

вот начинаю делать функцию, которая помечает на удаление записи или снимает их с дулаения. Я хочу, чтобы записи помечалиьс на удаление с помощью символа '!', а не удаляющиеся записи с символа '*'.

вот функцию пометка:
Код:
void Pometka(fstream& p, OURDATA dat, char* polFam, char pometka)
{
	p.clear();
	for(int i = 1; Read(p, dat, i); ++i)
		if((strcmp(dat.fam, polFam)) == 0) 
		{
			*dat.pmt = pometka;
			Write(p, dat, 0);
		};
}
polFam - это фамилия рабочего, которое нужно удалить, а pometka - символ, который вставляется с самого начала

так вот, на этапе построения у меня возникают ошибки:
Linking...
main.obj : error LNK2005: "char * NameTmp" (?NameTmp@@3PADA) already defined in Delete.obj
main.obj : error LNK2005: "char * NameFile" (?NameFile@@3PADA) already defined in Delete.obj
Manip.obj : error LNK2005: "char * NameTmp" (?NameTmp@@3PADA) already defined in Delete.obj
Manip.obj : error LNK2005: "char * NameFile" (?NameFile@@3PADA) already defined in Delete.obj
ReadFromFile.obj : error LNK2005: "char * NameTmp" (?NameTmp@@3PADA) already defined in Delete.obj
ReadFromFile.obj : error LNK2005: "char * NameFile" (?NameFile@@3PADA) already defined in Delete.obj
TablePrint.obj : error LNK2005: "char * NameTmp" (?NameTmp@@3PADA) already defined in Delete.obj
TablePrint.obj : error LNK2005: "char * NameFile" (?NameFile@@3PADA) already defined in Delete.obj
VvodVivod.obj : error LNK2005: "char * NameTmp" (?NameTmp@@3PADA) already defined in Delete.obj
VvodVivod.obj : error LNK2005: "char * NameFile" (?NameFile@@3PADA) already defined in Delete.obj
ZapisInFile.obj : error LNK2005: "char * NameTmp" (?NameTmp@@3PADA) already defined in Delete.obj
ZapisInFile.obj : error LNK2005: "char * NameFile" (?NameFile@@3PADA) already defined in Delete.obj
Delete.obj : error LNK2001: unresolved external symbol "void __cdecl Write(class std::basic_fstream<char,struct std::char_traits<char> > &,struct OURDATA const &,int)" (?Write@@YAXAAV?$basic_fstream@DU?$ char_traits@D@std@@@std@@ABUOURDATA @@H@Z)
D:\Барахло\Проекты на Visual Studio\Семестр 2\martirosyan_6\Release\martirosyan _6.exe : fatal error LNK1120: 1 unresolved externals
Build log was saved at "file://d:\Барахло\Проекты на Visual Studio\Семестр 2\martirosyan_6\Release\BuildLog.ht m"
martirosyan_6 - 14 error(s), 0 warning(s)


из-за чего возникают эти ошибки?

Последний раз редактировалось mat90x; 03.05.2008 в 01:32.
mat90x вне форума Ответить с цитированием
Старый 03.05.2008, 01:51   #3
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

По несколько раз Вы одинаковые функции определяете (в частности один раз - в ZapisInFile.cpp, второй в Delete.cpp, третий - в ReadFromFile.cpp и т.д.)
B_N вне форума Ответить с цитированием
Старый 03.05.2008, 12:20   #4
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

вы хотите сказать, что функцию Write омжно использовать только один раз?
mat90x вне форума Ответить с цитированием
Старый 03.05.2008, 17:26   #5
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

как тогда должна выглядеть эта функция?
mat90x вне форума Ответить с цитированием
Старый 03.05.2008, 20:44   #6
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

вот у меня код моей программы, с подробными комментариями! Скажите пожайлуста, что здесь у меня неправильно!

Код:
#include "head.h"
void Pometka(fstream& p, OURDATA dat, char* polFam, char pometka)
//функция помечает символом pometka запись если фамилия записи dat.fam 
//совпадает с введенной фамилией пользователя polFam
{
	p.clear();//очищаем поток от всех флагов
	for(int i = 1; Read(p, dat, i); ++i)//читаем все записи
		if((strcmp(dat.fam, polFam)) == 0) 
		{
			*dat.pmt = pometka;//если фамилии совпали, то помечаем эту запись
			Write(p, dat, 0);//записываем ее обратно в файл
		};
}
Код:
#include "head.h"
ostream& tabline(ostream& p)//манипулятор, рисующий нижнюю линию
{
	p<<setw(80)<<setfill('_')<<'_';
	return p;
}
ostream& shapka(ostream& p)//манипулятор, рисующий шапку таблицы
{
	p<<tabline;
	p<<"  |";
    p<<setw(10)<<setfill(' ')<<"Таб. номер"<<'|';
	p<<setw(37)<<setfill(' ')<<"Фамилия рабочего          "<<'|';
	p<<setw(13)<<setfill(' ')<<"Номер цеха  "<<'|';
	p<<setw(13)<<setfill(' ')<<"Зарплата  "<<'|';
	p<<tabline;
	return p;
}
Код:
#include "head.h"
fstream& Read(fstream& p, OURDATA& dat, int otkuda)
//функция читает из файла, с позиции (otkuda-1) и записывает информацию в dat
{
	p.clear();
	if(otkuda)
		p.seekg((otkuda - 1)*sizeof(dat), ios::beg);
	p.read((char*)& dat, sizeof(dat));
	if(!p && !p.eof())//не возвращаем !p и !p.eof()
	{
		cout<<"Ошибка чтения!";
		getch();
		exit(0);
	}
	return p;//возвращаем состояние либо good, либо eof
}
Код:
#include "head.h"
void TablePrint(fstream& p, OURDATA& dat)
//функция выводит все записи в виде таблицы
{
	cout<<shapka;//нарисовали шапку
	for(int i = 1; Read(p, dat, i); ++i)
		VivodInfo(dat);
}
Код:
#include "head.h"
void VvodInfo(OURDATA& dat)
//функция организует ввод пользователем информации
{
	cout<<endl<<"Введите табельный номер рабочего:\t";
	cin>>dat.tabNum;
	cout<<endl<<"Введите фамилию рабочего:\t";
	cin>>dat.fam;
	cout<<endl<<"Введите номер цеха:\t";
	cin>>dat.cexNum;
	cout<<endl<<"Введите среднюю зарплату:\t";
	cin>>dat.salary;
}
void VivodInfo(OURDATA& dat)
//функция выводит информацию в виде строки таблицы
{
	cout<<setw(2)<<"  ";
	cout<<setw(7)<<setfill(' ')<<dat.tabNum;
    cout<<setw(30)<<setfill(' ')<<dat.fam;
	cout<<setw(20)<<setfill(' ')<<dat.cexNum;
    cout<<setw(16)<<setfill(' ')<<dat.salary;
	cout<<endl<<endl;
}
Код:
#include "head.h"
void Write(fstream& p, OURDATA& dat, int kuda)
//функция записывает одну запись в (kuda-1) позицию
{
	p.clear();//очистили все флаги в потоке
	if(kuda)
		p.seekg((kuda - 1)*sizeof(OURDATA), ios::beg);
	    //если указали куда пишем запись, то записывается она на (kuda - 1) байтов, от начла файла
	    //иначе пишем в самое начло файла
	p.write((char*)& dat, sizeof(OURDATA));//записываем sizeof(OURDATA) - символов в p из dat
	if(!p)
	{
		cout<<endl<<"Ошибка записи!";
		getch();
		exit(0);
	}

}
void ZapisFile(fstream& p, int n, OURDATA& dat)
//функция записывает n-записей в файл
{
	
	p.clear();
	p.seekg(0, ios::end);//записываем в конец файла
	for(int i = 0; i < n; ++i)
	{
		VvodInfo(dat);
		Write(p, dat, 0);
	}
	cout<<endl<<"Записано "<<n<<" записей!";
}
mat90x вне форума Ответить с цитированием
Старый 03.05.2008, 20:46   #7
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

вторая часть кода

main:
Код:
#include "head.h"
void main(void)
{   
	setlocale(LC_ALL, ".1251");
	int itemMenu1, //для основного меню
		itemMenu2, //для меню пометок
		nZap, //номер записи
		//kolZap, //общее количество записей
		nRead; //позичия, откуда считаем
	OURDATA dat; //для записи данных
	char ans, //для выбора меню
		polFam[20]; //для выбора фамилии
	fstream p (NameFile, ios::in | ios::app | ios::binary);//флаги: для режима записи, для добавления записей в конец файла, binary-файл
	do
	{
		cout<<"1 - записать в файл"<<endl<<"2 - прочитать из файла"<<endl<<"3 - выдать всю информацию"<<endl
			<<"4 - пометить записи на удаление или снять записи с удаления"<<endl<<"5 - удалить помеченные записи";
		cout<<endl<<"Что вы хотите сделать?\t";
		cin>>itemMenu1;
		switch(itemMenu1)
		{
		case 1://записываем nZap-записей
			cout<<endl<<"Сколько раз хотите записать?\t";
			cin>>nZap;
			ZapisFile(p, nZap, dat);
			break;
		case 2://читаем с nRead-позиции
			cout<<endl<<"Какую запись хотите прочитать?\t";
		    cin>>nRead;
			Read(p, dat, nRead);//Read "кладет" в dat инофрмацию о рабочем
			if(!p.eof()) VivodInfo(dat);//VivodInfo выводит эту информацию
			else cout<<"\nНет такой записи!";
			break;
		case 3://выводим все записи в виде таблицы
			TablePrint(p, dat);
			break;
		case 4://пометка записей
			cout<<"1 - пометить на удаление"<<endl<<"2 - снять признак удаления";
			cout<<endl<<"Что вы хотите сделать?\t";
			cin>>itemMenu2;
			switch(itemMenu2)
			{
			case 1:
				cout<<endl<<"Ведите фамилию рабочего, которого хотите пометить:\t";
				cin>>polFam;
				Pometka(p, dat, polFam, '!');
				break;
			case 2:
				cout<<endl<<"Введите фамилию рабочего, с которого вы хотите снять признак удаления:\t";
				cin>>polFam;
				Pometka(p, dat, polFam, '*');
				break;
			}
			break;
		case 5:
			break;
		}
		cout<<endl<<"Повторить?(y/n)\t";
		cin>>ans;
	}while(ans == 'y' || ans == 'Y');
	cout<<"\nРабота закончена!";
	_getch();
}
.h:
Код:
//Структура записи: Табельный номер рабочего,  его фамилия, номер цеха, в котором работает, средняя зарплата.
#ifndef _MY_H
#define _MY_H
#include <iostream>
#include <conio.h>
#include <iomanip>
#include <fstream>
using namespace std;
char NameFile[20]  = "Workers";//название файла
char NameTmp[20] = "Tmp";
struct OURDATA
{
	char pmt[2];
	char tabNum[5];
	char fam[20];
	char cexNum[5];
	char salary[7];
};
void VvodInfo(OURDATA& dat);
void VivodInfo(OURDATA& dat);
void Write(fstream& p, const OURDATA& dat, int kuda);
void ZapisFile(fstream& p, int n, OURDATA& dat);
fstream& Read(fstream& p, OURDATA& dat, int otkuda);
ostream& tabline(ostream& p);
ostream& shapka(ostream& p);
void TablePrint(fstream& p, OURDATA& dat);
void Pometka(fstream& p, OURDATA dat, char* polFam, char pometka);
#endif
mat90x вне форума Ответить с цитированием
Старый 03.05.2008, 20:52   #8
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

Выложите целиком проект. Только ради Бога, не на депозит, а скажем на http://mihd.net/
B_N вне форума Ответить с цитированием
Старый 03.05.2008, 22:20   #9
mat90x
Пользователь
 
Аватар для mat90x
 
Регистрация: 19.04.2008
Сообщений: 22
По умолчанию

все для вас!
http://mihd.net/o942jdm

P.S. я забыл сказать, но может это поможет! Сначала я использовал в функции Pometka функцию Write, появились две последние ошибки, которые постами выше у меня окрашены в красный, все то же на этапе выполнения! Потом я создал в функции Delete новый поток, переписал в него все записи, но с пометками, удалил старый файл(remove) и переименовал новый файл в старый(rename) и уже тогда появилиьс эти 14 ошибок! Может я что-то неправильно сделал?
mat90x вне форума Ответить с цитированием
Старый 03.05.2008, 23:32   #10
B_N
Новичок
Джуниор
 
Регистрация: 18.01.2008
Сообщений: 1,720
По умолчанию

1. Уберите из заголовка (!) head.h объявления
Код:
char NameFile[20]  = "Workers";//название файла
char NameTmp[20] = "Tmp";
Заголовок подключается во всех файлах и получается, что в каждом cpp-файле объявляются эти массивы с одинаковыми именами. Само собой, это никогда не понравится линкеру. Перенесите их в main.cpp для строгости.

2. Функция Write объявлена (head.h) как
Код:
void Write(fstream& p, const OURDATA& dat, int kuda);
а определена (ZapisInFile.cpp) как
Код:
void Write(fstream& p, OURDATA& dat, int kuda)
несовпадение типов налицо - отсюда крики линкера. Добавьте во втором случае const.
B_N вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с потоками DeeNamid Общие вопросы Delphi 2 04.08.2008 17:36
работа с потоками Alex_Pro Общие вопросы .NET 1 01.07.2008 07:25
Как грамотно разделить данные между потоками? bagulma Общие вопросы Delphi 5 28.05.2008 22:41
Проблема с потоками vitalik007 Общие вопросы Delphi 1 11.03.2008 22:35
Ошибка при работе с потоками vitalik007 Общие вопросы Delphi 6 09.03.2008 09:25