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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 10.04.2015, 18:13   #1
Александр Шатило
Пользователь
 
Регистрация: 18.01.2015
Сообщений: 29
Сообщение Списки

При выводе списка на экран выводит непонятные символы, как это исправить?
Вот код:
Код:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

struct Adr
{
	char name[30]; 
	char street[40];
	char city[20];
	struct Adr *next;
	struct Adr *prev;
};

struct Adr *head; 
struct Adr *last;

int Menu(void)
{
	char s[80];   
	int c;
	cout << endl;
	cout << "1. Ввод имени" << endl;
	cout << "2. Удаление имени" << endl;
	cout << "3. Вывод списка на экран" << endl;
	cout << "4. Поиск" << endl;
	cout << "5. Сохранить в файл" << endl;
	cout << "6. Загрузить из файла" << endl;
	cout << "7. Выход" << endl; cout << endl;
	do
	{
		cout << "Ваш выбор: "; 
		gets_s(s);  
		cout << endl;
		c = atoi(s);
	} 
	while (c<0 || c>7);
	return c;
}

void Sozdat(Adr *i, Adr **head, Adr **last)
{
	struct Adr *old, *p;
	if (*last == NULL)
	{
		i->next = NULL; 
		i->prev = NULL;
		*last = i;  
		*head = i;
		return;
	}
	p = *head; 
	old = NULL;
	while (p)
	{
		if (strcmp(p->name, i->name)<0)
		{
			old = p; 
			p = p->next;
		}
		else
		{
			if (p->prev)
			{
				p->prev->next = i; 
				i->next = p;
				i->prev = p->prev;  
				p->prev = i;
				return;
			}
			i->next = p; 
			i->prev = NULL;
			p->prev = i; 
			*head = i;
			return;
		}
	}
	old->next = i;
	i->next = NULL;  
	i->prev = old;
	*last = i;
}

void Vvod(char *prompt, char *s, int count)
{
	char p[255];
	do
	{
		cout << (prompt); fgets(p, 254, stdin);
		if (strlen(p) > count) cout << ("Слишком длинная строка");  
	} 
	while (strlen(p) > count);
	p[strlen(p) - 1] = 0;  
	strcpy_s(p, s);
}

void VvodSp(void)   
{
	struct Adr *t; 
	int i;
	t = new (struct Adr);
	if (!t) 
	{ 
		cout << ("Нет свободной памяти"); 
		return; 
	}
	Vvod("Введите имя: ", t->name, 30);
	Vvod("Введите улицу: ", t->street, 40);
	Vvod("Введите город: ", t->city, 20);
	Sozdat(t, &head, &last);
}

void VyvodSp(void)  
{
	struct Adr *t;  
	t = head;
	while (t)
	{
		cout << t->name << " " << t->street << " " << t->city << endl; 
		t = t->next;
	}  
	cout << " " << endl;
}	

void Poisk(void) 
{
	char name[40];  
	struct Adr *t;  
	t = head;
	cout << "Введите имя: "; 
	gets_s(name);
	while (t)
	{
		if (!strcmp(name, t->name)) break;
		t = t->next;
	}
	if (!t) cout << "Имя не найдено" << endl;
	else cout << t->name << ' ' << t->street << ' ' << t->city << endl;
}

void Udalit(Adr **head, Adr **last)
{
	struct Adr *t;  
	char name[40]; 
	t = *head;
	cout << "Введите имя: "; 
	gets_s(name);
	while (t)
	{
		if (!strcmp(name, t->name)) break;
		t = t->next;
	}
	if (t)
	{
		if (*head == t)
		{
			*head = t->next;
			if (*head) (*head)->prev = NULL;
			else *last = NULL;
		}
		else 
		{
			t->prev->next = t->next;
			if (t != *last) t->next->prev = t->prev;
			else  *last = t->prev;
		}
		delete t;
	}
}

void Zapisat(void)       
{
	struct Adr *t;  
	FILE *fp;
	fopen_s(&fp, "d:\\mlist.bin", "wb");
	if (!fp) 
	{ 
		cout << "Файл не открывается" << endl;  
		exit(1); 
	}
	cout << "Сохранение в файл" << endl;
	t = head;
	while (t) 
	{
		fwrite(t, sizeof(struct Adr), 1, fp);
		t = t->next;
	}      
	fclose(fp);
}

void Schitat()
{
	struct Adr *t;  
	FILE *fp;
	fopen_s(&fp, "d:\\mlist.bin", "rb");
	if (!fp) 
	{ 
		cout << "Файл не открывается" << endl;  
		exit(1); 
	}
	while (head)
	{
		last = head->next; 
		delete head;
		head = last;
	}   
	head = last = NULL;
	cout << "Загрузка из файла" << endl;
	while (!feof(fp))
	{
		t = new (struct Adr);
		if (!t) 
		{ 
			cout << "Нет свободной памяти" << endl; 
		    return; 
	    }
	    if (1 != fread(t, sizeof(struct Adr), 1, fp)) break;
	    Sozdat(t, &head, &last);
	}
	fclose(fp);
}

int main(void)
{
	setlocale(LC_CTYPE, "Rus");
	head = last = NULL;
	for (;;)
	{
		switch (Menu())
		{
		case 1: VvodSp();  break;
		case 2: Udalit(&head, &last); break;
		case 3: VyvodSp(); break;
		case 4: Poisk();   break;
		case 5: Zapisat(); break;
		case 6: Schitat(); break;
		case 7: exit(0);
		}
	}   return 0;
}
Тишка

Последний раз редактировалось Stilet; 10.04.2015 в 18:44.
Александр Шатило вне форума Ответить с цитированием
Старый 10.04.2015, 18:52   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Я правильно понимаю: отладку ты не производил, и проверки что же на самом деле вводиться не делались?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.04.2015, 19:00   #3
Александр Шатило
Пользователь
 
Регистрация: 18.01.2015
Сообщений: 29
По умолчанию

Вот скрин программы:
Изображения
Тип файла: jpg Безымянный.jpg (12.0 Кб, 111 просмотров)
Тишка
Александр Шатило вне форума Ответить с цитированием
Старый 10.04.2015, 20:03   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

М.м.м... Понятно... Не делал...
Тогда изучай функцию strcpy_s() внимательнее (https://msdn.microsoft.com/ru-ru/lib...vs.110%29.aspx)
Ты параметры перепутал.

Ну и чтоб "окончательно запутать" предложу свое видение:
Код:
#include <iostream>
#include <string.h>
#include <fstream>
using namespace std;

struct Adr
{
	char name[30];
	char street[40];
	char city[20];
	// Инкапсулируем методы ввода и вывода в стркутуру
	void Vvod(char *prompt,int k,int count){
        char p[255];
        do
        {
            cout << (prompt); fgets(p, 254, stdin);
            if (strlen(p) > count) cout << ("Слишком длинная строка");
        }
        while (strlen(p) > count);
        p[strlen(p) - 1] = 0;
        switch(k){
            case 1: strcpy(name,p); break;
            case 2: strcpy(street,p); break;
            case 3: strcpy(city,p); break;
        }
    };
    void Vivod(){
        cout<<name<<'\t'<<street<<'\t'<<city<<'\n';
    }
	struct Adr *next;
	struct Adr *prev;
};

struct Adr *head;
struct Adr *last;

void VvodSp(void)
{
	struct Adr *t;
	int i;
	t = new (struct Adr);
	if (!t)
	{
		cout << ("Нет свободной памяти");
		return;
	}
	//Вместо передачи указателя работаем с методами
	t->Vvod("Введите имя: ",1, 30);
	t->Vvod("Введите улицу: ", 2, 40);
	t->Vvod("Введите город: ", 3, 20);
    t->Vivod();
}
int main()
{
    setlocale(LC_CTYPE, "Rus");
	head = last = NULL;
	VvodSp();
    cin.get();
    return 0;
}
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.04.2015, 22:04   #5
Александр Шатило
Пользователь
 
Регистрация: 18.01.2015
Сообщений: 29
По умолчанию

А можно как-нибудь без метода ввода и вывода структуры сделать обычными функциями?
Тишка
Александр Шатило вне форума Ответить с цитированием
Старый 11.04.2015, 06:37   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Можно. Для начала прочитай внимательно что я написал по поводу перепутанных параметров )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


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

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
списки _Аександр_ Общие вопросы C/C++ 4 27.10.2013 21:42
Списки ant93 Visual C++ 0 30.05.2013 14:27
Списки ant93 Общие вопросы C/C++ 0 29.05.2013 15:54
Списки lialia Паскаль, Turbo Pascal, PascalABC.NET 0 25.05.2013 18:34