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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 20.05.2013, 17:23   #11
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

Цитата:
Сообщение от NewLamer&Programer Посмотреть сообщение
1. что за новый параметр?
2. почему открываем на "rb", а не "r"?
3. зачем перевод указателя в конец он же и так в конце вроде при открытии?
4. вот эта строка совсем не понятна: "*len = ftell(fp) / sizeof(TPhoneBook);"
5. что за rewind и зачем она?
7. да кстати тоже подумал о том что можно наверное считывать всю структуру, а не по пунктам, это хорошо
8. еще не сталкивался с формой записи **PB, зачем это?
9. и кстати куда вы дели цикл??? там же массив структур, а не один экземпляр
1) Иначе вызывающая функция никак не сможет узнать о количестве элементов в массиве.
2) Чтобы программа не меняла байты \n и \r при считывании.
3) При открытии указатель в начале файла.
4) После переноса указателя в конец узнаем количество байт в файле и делим на размер 1 записи.
5) rewind устанавливает указатель на начало файла.
6) забыт
7) без комментариев
8) Вы же хотите вернуть через этот параметр массив? Чтобы так сделать нужно передать указатель на указатель на массив, иначе Вы измените только фактический параметр функции, но не сам указатель на элементы, который был передан в функцию
Срочно подтягивать знания по работе с указателями в си.
9) Зачем цикл? Считываю сразу все структуры из файла.

Вызов функции:
Код:
TPhoneBook *PB = NULL;
long len = 0;
Load(&PB, &len);
Также, гораздо быстрее ввести название неизвестной функции в гугл, чем ждать ответа по полдня.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 20.05.2013, 18:41   #12
NewLamer&Programer
Форумчанин
 
Регистрация: 23.11.2012
Сообщений: 428
По умолчанию

BDA, спасибо

вот еще переделал Save по аналогии

Код:
void Save(TPhoneBook **PB, long *COUNT)
{
    FILE *fp;
    if((fp = fopen(FileName, "rb")) == NULL) 
    {
        printf("Ошибка при открытии файла.");
        return;
    }
    fseek(fp, 0, SEEK_END);
    *COUNT = ftell(fp) / sizeof(TPhoneBook);
    rewind(fp);
    *PB = (TPhoneBook *) malloc(*COUNT * sizeof(TPhoneBook));
    fwrite(*PB, sizeof(TPhoneBook), *COUNT, fp);
    fclose(fp);
}
п.с. еще не понял только почему long, а не int? (у len)

тоже проверьте пожалуста

Код:
void Add(TPhoneBook *EPB, TPhoneBook **PB, int *COUNT)
{
	*COUNT++;
	*PB = (TPhoneBook *)malloc(*COUNT * sizeof(TPhoneBook));
	*PB[*COUNT] = EPB;
}

void Delete(TPhoneBook **PB, int *N, int *COUNT)
{
	int i;
	for (i = *N; i < *COUNT; i++)
		*PB[i] = *PB[i+1];
	*COUNT--;
	*PB = (TPhoneBook *)malloc(*COUNT * sizeof(TPhoneBook));
}

void Change(TPhoneBook *EPB, TPhoneBook **PB, int *N)
{
	*PB[*N] = *EPB;
}

Последний раз редактировалось Stilet; 21.05.2013 в 23:13.
NewLamer&Programer вне форума Ответить с цитированием
Старый 20.05.2013, 18:54   #13
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

"Смешались в кучу кони, люди"
Не нужно просто повторять код, нужно его понять и использовать.
Код:
void
Save(TPhoneBook *PB, long COUNT)
{
    FILE *fp;
    if((fp = fopen(FileName, "wb")) == NULL) 
    {
        printf("Ошибка при открытии файла.");
        return;
    }
    fwrite(PB, sizeof(TPhoneBook), COUNT, fp);
    fclose(fp);
}

void
Add(TPhoneBook EPB, TPhoneBook **PB, int *COUNT)
{
    *PB = (TPhoneBook *) realloc(*PB, (*COUNT + 1) * sizeof(TPhoneBook));
    *PB[*COUNT++] = EPB;
}

void
Delete(TPhoneBook **PB, int N, int *COUNT)
{
    int i;
    for (i = N; i < *COUNT - 1; i++)
        *PB[i] = *PB[i+1];
    *PB = (TPhoneBook *) realloc(*PB, (--*COUNT) * sizeof(TPhoneBook));
}

void
Change(TPhoneBook EPB, TPhoneBook *PB, int N)
{
    PB[N] = EPB;
}
В change и add неплохо проверять на выход за границы массива.
Нумерация в массиве 0..COUNT-1.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 21.05.2013 в 15:08.
BDA вне форума Ответить с цитированием
Старый 21.05.2013, 11:17   #14
NewLamer&Programer
Форумчанин
 
Регистрация: 23.11.2012
Сообщений: 428
По умолчанию

BDA, не подскажете как к ним правильно обращаться? (да, для меня воистину самой сложной темой являются указатели никак не понять...) и еще в функциях Save, Load почему COUNT типа long, а не int? просто у меня COUNT глобальный типа int... и остальные функции под int, ничего если заменю и тут на int?
NewLamer&Programer вне форума Ответить с цитированием
Старый 21.05.2013, 15:12   #15
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

Код:
TPhoneBook *PB = NULL;
TPhoneBook b;
long len = 0;
int n = 4;
Load(&PB, &len);
Save(PB, len);
Add(b, &PB, &len);
Delete(&PB, n, &len);
Change(b, PB, n);
Функция ftell возвращает long int (поэтому взял этот тип).
Цитата:
Глобальные переменные должны использоваться только при необходимости. Передача параметров предпочтительнее использования глобальных переменных.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 26.05.2013, 12:58   #16
NewLamer&Programer
Форумчанин
 
Регистрация: 23.11.2012
Сообщений: 428
По умолчанию

BDA, подсобите пожалуйста еще с одной функцией, кстати подозреваю, что ее не работа связана как то с add, т.к. теоретически она прямо однозначно должна
работать в общем начал с того что написал собственно функцию

Код:
void Show(TPhoneBook EPB, int Index)
{

	setlocale(LC_ALL, "RUSSIAN");

	{
		printf("|---------------------------------------------------------------------------------------------------------------------------------------|\n");
		printf("|%-3d|%-10s|%-10s|%-15s|%-6s|%-6s|%-12s|%-10s|%-10s|%-15s|%-3s|%-3s|%-20s|\n", Index, EPB.Family, EPB.Name, 
			EPB.Patronymic, EPB.Phone.Home, EPB.Phone.Work, EPB.Phone.Mobile, EPB.Address.Country, EPB.Address.City, 
			EPB.Address.Street, EPB.Address.N_Home, EPB.Address.N_Apartment, EPB.Email);
		printf("|---------------------------------------------------------------------------------------------------------------------------------------|\n");
	}
}
она для показа одного экземпляра PB, далее пишу для показа всех с использованием ее

Код:
void ShowAll(TPhoneBook *PB, int COUNT)
{
	int i;
	
	for(i=0;i<COUNT;i++)
		Show(PB[i],i);
}
компилируется все хорошо, но

Main.cpp
Код:
#include "Functions.h"

#define _CRT_SECURE_NO_WARNINGS

TPhoneBook *PB;
int COUNT = 0;

void main()
{
	setlocale(LC_ALL, "RUSSIAN");
	TPhoneBook EPB;
	system("mode con cols=137 lines=50");
	EPB = Interview();
	Add(EPB,&PB,&COUNT);
	Add(EPB,&PB,&COUNT);
	Add(EPB,&PB,&COUNT);
	ShowAll(PB,COUNT);
	getch();
}
ввожу все, а потом просто консоль закрывается что не так?
NewLamer&Programer вне форума Ответить с цитированием
Старый 26.05.2013, 15:39   #17
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

Код:
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
#include <string.h>

typedef struct TPhoneBook
{
    int N;
    char Family;
    char Name;
    char Patronymic;
    struct Phone
    {
        int Home;
        int Work;
        int Mobile;
    } Phone;
    struct Address
    {
        char Country;
        char City;
        char Street;
        int N_Home;
        int N_Apartment;
    } Address;
    char Email;
} TPhoneBook;

void
Save(TPhoneBook *PB, long COUNT, char *FileName)
{
    FILE *fp;
    if((fp = fopen(FileName, "wb")) == NULL)
    {
        printf("Ошибка при открытии файла.");
        return;
    }
    fwrite(PB, sizeof(*PB), COUNT, fp);
    fclose(fp);
}

void
Load(TPhoneBook **PB, long *len, char *FileName)
{
    FILE *fp;
    if((fp = fopen(FileName, "rb")) == NULL)
    {
        printf("Ошибка при открытии файла.");
        return;
    }
    fseek(fp, 0, SEEK_END);
    *len = ftell(fp) / sizeof(**PB);
    rewind(fp);
    *PB = (TPhoneBook *) malloc(*len * sizeof(**PB));
    fread(*PB, sizeof(**PB), *len, fp);
    fclose(fp);
}

void
Add(TPhoneBook EPB, TPhoneBook **PB, int *COUNT)
{
    *PB = (TPhoneBook *) realloc(*PB, (*COUNT + 1) * sizeof(**PB));
    (*PB)[(*COUNT)++] = EPB;
}

void
Delete(TPhoneBook **PB, int N, int *COUNT)
{
    int i;
    for (i = N; i < *COUNT - 1; i++)
        (*PB)[i] = (*PB)[i+1];
    *PB = (TPhoneBook *) realloc(*PB, (--(*COUNT)) * sizeof(**PB));
}

void
Change(TPhoneBook EPB, TPhoneBook *PB, int N)
{
    PB[N] = EPB;
}

void
Show(TPhoneBook EPB, int Index)
{
    printf("|---------------------------------------------------------------------------------------------------------------------------------------|\n");
    //printf("|%-3d|%-10s|%-10s|%-15s|%-6s|%-6s|%-12s|%-10s|%-10s|%-15s|%-3s|%-3s|%-20s|\n", Index, EPB.Family, EPB.Name,
    printf("|%-3d|%-10c|%-10c|%-15c|%-6d|%-6d|%-12d|%-10c|%-10c|%-15c|%-3d|%-3d|%-20c|\n", Index, EPB.Family, EPB.Name,
        EPB.Patronymic, EPB.Phone.Home, EPB.Phone.Work, EPB.Phone.Mobile, EPB.Address.Country, EPB.Address.City,
        EPB.Address.Street, EPB.Address.N_Home, EPB.Address.N_Apartment, EPB.Email);
    printf("|---------------------------------------------------------------------------------------------------------------------------------------|\n");
}

void
ShowAll(TPhoneBook *PB, int COUNT)
{
	int i;
	for(i = 0; i < COUNT; ++i)
		Show(PB[i], i);
}

void
Interview(TPhoneBook *PB)
{
    memset(PB, 0, sizeof(*PB));
    (*PB).Phone.Home = 123;
}

int
main()
{
    setlocale(LC_ALL, "RUSSIAN");
    TPhoneBook *PB = NULL;
    int COUNT = 0;
    TPhoneBook EPB;
    system("mode con cols=137 lines=50");
    Interview(&EPB);
    Add(EPB,&PB,&COUNT);
    Add(EPB,&PB,&COUNT);
    Add(EPB,&PB,&COUNT);
    ShowAll(PB,COUNT);
    getch();
    free(PB);
    return 0;
}
Действительно были ошибки в Add.
Если Вы думаете, что поля Фамилия, Имя и другие содержат строки, то Вы ошибаетесь, они содержат только 1 символ.
В printf заданы были неправильные спецификаторы вывода.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 26.05.2013 в 15:41.
BDA вне форума Ответить с цитированием
Старый 26.05.2013, 15:49   #18
NewLamer&Programer
Форумчанин
 
Регистрация: 23.11.2012
Сообщений: 428
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Действительно были ошибки в Add.
Если Вы думаете, что поля Фамилия, Имя и другие содержат строки, то Вы ошибаетесь, они содержат только 1 символ.
В printf заданы были неправильные спецификаторы вывода.
спасибо

Цитата:
Сообщение от BDA Посмотреть сообщение
Если Вы думаете, что поля Фамилия, Имя и другие содержат строки, то Вы ошибаетесь, они содержат только 1 символ.
а как сделать правильно?

п.с. кстати вы зря поправили поля структуры касающиеся номеров, т.к. номера домов, квартир бывают со всякими доп. обозначениями типа 9-б, и телефоны мобильные так уже точно можно писать как +7960... то есть все же лучше char, а не int
NewLamer&Programer вне форума Ответить с цитированием
Старый 26.05.2013, 15:52   #19
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,430
По умолчанию

Хотя бы:
Код:
typedef struct TPhoneBook
{
    int N;
    char Family[20];
    char Name[20];
    char Patronymic[20];
    struct Phone
    {
        int Home;
        int Work;
        int Mobile;
    } Phone;
    struct Address
    {
        char Country[20];
        char City[20];
        char Street[20];
        int N_Home;
        int N_Apartment;
    } Address;
    char Email[20];
} TPhoneBook;
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 26.05.2013, 15:54   #20
NewLamer&Programer
Форумчанин
 
Регистрация: 23.11.2012
Сообщений: 428
По умолчанию

а что изменилось? typedef? зачем?

вот так у меня объявлена структура сейчас:

Код:
#ifndef PHONEBOOK_H
#define PHONEBOOK_H
#define FileName  "PhoneBook.bin"

struct TPhoneBook
{
	char Family[100];
	char Name[100];
	char Patronymic[100];
	struct TPhone
	{
		char Home[100];
		char Work[100];
		char Mobile[100];
	} Phone;
	struct TAddress
	{
		char Country[100];
		char City[100];
		char Street[100];
		char N_Home[100];
		char N_Apartment[100];
	} Address;
	char Email[100];
};
#endif
кстати уже раздражает везде char, почему нельзя просто как в делфи сделать тип string?

Последний раз редактировалось NewLamer&Programer; 26.05.2013 в 16:04.
NewLamer&Programer вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Загрузка из файла динамического массива структур Astronomy Общие вопросы C/C++ 1 27.12.2011 21:32
запись и загрузка с бинарного файла массива структур zetaBiT Общие вопросы C/C++ 14 28.08.2011 23:24
Сохранение и загрузка динамического массива. SkAndrew Общие вопросы Delphi 0 05.05.2010 15:54
Заполнение массива структур данными из файла Brutallus Общие вопросы C/C++ 0 26.11.2009 19:01