Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Работа с потоками в СИ++

39K
10 января 2011 года
Tequilla
24 / / 19.10.2009
Написал программу одна из функций которой записывает в файл элементы бинарного дерева поиска.
все работает отлично (но только в том случае. если файл уже был создан на диске)
а если в начале(а именно в 26 строке записать ofstream outFile("TREE.txt");)
то он тогда создаст файл, если его небыло на диске., но записывать в него ничего не станет
и вот я не могу понять в чем причина?
Если кто-то может помочь , я буду очень признателен!

Вот код программы:

#include <vcl.h>
#pragma hdrstop
#include<conio.h>
#include<iostream.h>
#include<stdio.h>
#include<math.h>
#include<ctime>
#include<fstream>

using std::system;

struct TREE
{
int value;
TREE *pLeft;
TREE *pRight;
};//end of struct TREE


TREE *root = new TREE;
String A[10000];
TREE *Parent;
int h = 0;//расстояние для функции PrintTree()
int N=10;//первоначальный размер дерева
int K=0;
ofstream outFile;//Описание потока для вывода


void Menu()//Основное меню програмы
{
cout<<"\tMain menu:"<<endl;
cout<<"1. Create new tree:"<<endl; //Создать дерево
cout<<"2. Print tree:"<<endl; //Печать дерева
cout<<"3. Add new element:"<<endl; //Добавление нового элемента
cout<<"4. Delete element:"<<endl; //Удаление элемента
cout<<"5. Show tree as array:"<<endl; //Представить дерево в виде массива
cout<<"6. Save tree to file: "<<endl; //Сохранить дерево в файл
cout<<"7. Look Depth of tree:"<<endl; //Вычислить глубину дерева
cout<<"ESC. Exit"<<endl; //выход из программы. Удаление дерева
} //Освобождение памяти


TREE* MakeTree(TREE *root, int node)
{//Функция построения дерева двоичного поиска
if (root == NULL)
{
root = new TREE;
root->value = node;
root->pLeft = root->pRight = NULL;
}
else
{
if(node <= root->value)
root->pLeft = MakeTree(root->pLeft, node);
else
root->pRight = MakeTree(root->pRight, node);
}
return root;
}//end of MakeTree function


TREE *deleteTree(TREE *root)//удаление дерева поиска
{ //Освобождение памяти
if(root)
{
deleteTree(root->pLeft);
deleteTree(root->pRight);
delete(root);
}
return NULL;
}//end of deleteTree function.


void PrintTree(TREE *root, int h)//Функция печати дерева
{
if(root)
{
PrintTree(root->pRight, h + 1);
for(int i = 1; i <= h; i++)
cout<<" ";
cout<<root->value<<endl;
PrintTree(root->pLeft, h + 1);
}
}//End of PrintTree function


TREE *find(int Record, TREE* root)//функция поиска
{
while (root != NULL)
{
if (Record == root->value)
break;
else
{
Parent = root;
if (Record < root->value)
root=root->pLeft;
else root=root->pRight;
}
}
return root;
}//end of Find Function


void DelRoot(int Record)//Функция удаления узла
{
TREE *delNode = NULL;
TREE *ReplaceNode = NULL;

if((delNode = find(Record, root)) == NULL)
return;

if(delNode->pRight == NULL)
ReplaceNode = delNode->pLeft;
else
if(delNode->pLeft == NULL)
ReplaceNode = delNode->pRight;
else
{
TREE *ParentRN = delNode;
ReplaceNode = delNode->pLeft;
while(ReplaceNode->pRight != NULL)
{
ParentRN = ReplaceNode;
ReplaceNode = ReplaceNode->pRight;
}
if(ParentRN == delNode)
{
ReplaceNode->pRight = delNode->pRight;
}
else
{
ParentRN->pRight = ReplaceNode->pLeft;
ReplaceNode->pLeft = delNode->pLeft;
ReplaceNode->pRight = delNode->pRight;
}
}
if(Parent == NULL)
root = ReplaceNode;
else
if(delNode->value < Parent->value)
Parent->pLeft = ReplaceNode;
else
Parent->pRight = ReplaceNode;
delete delNode;
}//end of Delete function


void save(TREE *ptr) //функция сохранения дерева в файл
{
if(ptr == root)
if(!outFile)
{
cout<<"Error...";
getch();
exit(0);
}
if(ptr)
{
save(ptr->pRight);
outFile <<"_"<< ptr->value << "_" << endl;
save(ptr->pLeft);
}
else return;
}//end of save function


int order(TREE *root,int mk,int k)
{//функция вычисления глубины дерева
if(!root)
{
mk = mk > k ? mk : k;
return mk;
}
k++;
mk = order(root->pLeft, mk, k);
mk = order(root->pRight, mk, k);

return mk;
}//end of order function


void TreeToArray(TREE *ptr, int i)
{//функция представления дерева в виде массива
if(ptr)
{
A = IntToStr(ptr->value);
K = K > 2 * i + 2? K : i;
if(ptr->pLeft) TreeToArray(ptr->pLeft, 2 * i + 1);
if(ptr->pRight) TreeToArray(ptr->pRight, 2 * i + 2);
}
}//end of TreeToArray function


int main(int argc, char* argv[])
{
clrscr();
int Deep = 0, MAX = 0;
srand((unsigned)time(NULL));//инициализируем генератор случайных чисел
root = NULL;
do
{
clrscr();
Menu();//вызываем меню программы
int Amount = 0;
switch(_getch())
{
case 49:
if(root == NULL)
{
for(int i = 0; i < N; i++)
root = MakeTree(root, rand()%50);//создание дерева
cout<<"tree was created"<<endl;
system("pause");
}
else
{
cout <<"tree had been already created"<< endl;
system("pause");
}
break;


case 50:
clrscr();
PrintTree(root, 0);//печать дерева
system("pause");
break;


case 51:
clrscr();
root = MakeTree(root, rand()%35);//добавление нового узла
cout<<"element added!"<<endl;
system("pause");
break;


case 52:
int DR;
cout<<"Print element, which you want to find: ";
cin>>DR;
DelRoot(DR);
break;


case 53:
for(MAX = Deep; MAX != 0; MAX--)
Amount += pow(2, MAX);
Amount += 1;
cout<<"Amount = "<<Amount<<endl;
TreeToArray(root, 0);
cout<<endl<<"Array: ";
for(int i = 0; i < Amount; i++)
{
if(A == "") A = "#";
printf("%s ", A);
}
getch();
break;


case 54:
outFile.open("TREE.txt", ios::in);
save(root);
system("pause");
break;


case 55:
Deep = order(root, 0, 0) - 1;
cout<<"Depth = "<<Deep;
MAX = pow(2, Deep);
cout<<"Max = "<<MAX;
getch();
break;


case 27:
deleteTree(root);
return 0;
break;

}

}while(true);
outFile.close();
}//End of main function
39K
10 января 2011 года
Tequilla
24 / / 19.10.2009
а о_0 нашел причину))
в 264 строке режим открытия указал не тот))

Только теперь другой вопрос : почему при сохранении он все отлично сохраняет, но если нажать следом еще раз сохранить то он вылетит ?
278
10 января 2011 года
Alexander92
1.1K / / 04.08.2008
для этого есть.
316
11 января 2011 года
Alm3n
889 / / 29.05.2009
Цитата: Tequilla
вылетит ?


пытается открыть уже открытый файл

392
12 января 2011 года
cronya
421 / / 03.01.2009
Цитата: Alm3n
пытается открыть уже открытый файл


не открыть, а перезаписать. Открывать можно до позеленения, а вот если симофор установлен на блокировку открытого файла который правят, доступа к нему по записи не будет, если его уже кто то правит).

Совет для Teqilla, делать открытие и закрытие файла после выполнения операций над ним.

316
12 января 2011 года
Alm3n
889 / / 29.05.2009
Цитата: cronya
если симофор установлен на блокировку открытого файла


где он установлен(устанавливает) в коде?

392
12 января 2011 года
cronya
421 / / 03.01.2009
Цитата: Alm3n
где он установлен(устанавливает) в коде?

Их система если чего устанавливает, почитай что такое семафоры, зачем глупые вопросы задавать.
ЗЫ: Раз уж начали бодягу разводить, покажи где написано, что Teqilla устанавливает в коде!

392
12 января 2011 года
cronya
421 / / 03.01.2009
Код:
[COLOR=DarkRed]void save(TREE *ptr)[/COLOR]    //функция сохранения дерева в файл
{
    if(ptr == root)
    if(!outFile)
    {
        cout<<"Error...";
        getch();
        exit(0);
    }
    if(ptr)
    {
[COLOR=DarkRed]         save(ptr->pRight);[/COLOR]
        outFile <<"_"<< ptr->value << "_" << endl;
        [COLOR=DarkRed]save(ptr->pLeft);[/COLOR]
    }
    else return;
}//end of save function

Воть что еще смущает, мб у вас так и работает, ну фунция не зацикливается случаем?
316
12 января 2011 года
Alm3n
889 / / 29.05.2009
Цитата: cronya
где написано, что Teqilla устанавливает в коде!


где я говорил,что это должно быть где-то написано?

Цитата:
Их система если чего устанавливает


ссылку в студию.сам не нашел.
ну и самвопрос:какую api вызывает метод open(win платформа)?

392
13 января 2011 года
cronya
421 / / 03.01.2009
Как надоело писькомерство.
1)
Цитата:
ссылку в студию.сам не нашел.
ну и самвопрос:какую api вызывает метод open(win платформа)?

Я вам не справочник, используйте www.google.ru там все есть.
2) Вы создали файловый поток, он обратился к файлу, создали второй файловый поток, обращаетесь к тому же файлу, но первый поток использует это уже файл == нет доступа к файлу, пока не закрыт 1 поток. Нет доступа, потому что выставлен флаг на его использования, файл - общий ресурс, потоки - разные процессы, ищите параллели.
ЭТО ФАКТ, и с этим не поспоришь! Можете проверить на практике.
Если у вас получиться по-другому, код в студию(winapi не использовать, потому что об этом и речи нету в коде Teqilla, к тому же fstream open и winapi open разные вещи)

39K
14 января 2011 года
Tequilla
24 / / 19.10.2009
Ребята всем спасибо, но я уже нашел в чем была проблема(просто забыл отписаться)
На самом деле все было гораздо проще , чем многие из вас думали))
Причина вылетов при повторном сохранении была в том, что открыв поток я его пытаюсь открыть еще раз, при этом закрытие потока было в конце main(). Так что Cronya был прав дав совет закрывать поток, когда он уже использовался!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог