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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.03.2013, 12:14   #1
ya2500
Пользователь
 
Регистрация: 03.03.2013
Сообщений: 12
Лампочка пытаюсь разобраться

когда-то программировал на Delphi. скачал бесплатный Visual C++ 2008 и пытаюсь разобраться. для этого решаю программерские задачки. возникающие вопросы и проблемы собираюсь писать в эту тему.
--

вопрос 1-й
создал консольное приложение с пререндеренным заголовком. параметры, с которыми запущена программа, оно помещает в массив типа _TCHAR:
int _tmain(int argc, _TCHAR* argv[])
а я хочу, чтобы параметром передавалось имя файла, для дальнейшего его использования функцией fopen. что делать?
--

вопрос 2-й
вообще я хочу из файла занести данные в двумерный массив. в задаче сказано: "Пустая клетка представлена символом '.', закрашенная - символом '#'. Число строк и столбцов не превышает 500.". я так понимаю, что это означает, что мне придётся использовать массив 500х500. и я погуглил всякие тексты, но пока так толком и не понял: как мне эти данные занести в массив?
ya2500 вне форума Ответить с цитированием
Старый 03.03.2013, 12:32   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
я хочу, чтобы параметром передавалось имя файла
argv[1] даст тебе указатель на имя файла. Если не ошибаюсь то fopen(argv[1]...) писать будешь.
Цитата:
как мне эти данные занести в массив?
Как выглядят данные в файле?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 03.03.2013, 13:13   #3
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,120
По умолчанию

ya2500

вопрос 1-й
создал консольное приложение с пререндеренным заголовком. параметры, с которыми запущена программа, оно помещает в массив типа _TCHAR:
int _tmain(int argc, _TCHAR* argv[])
а я хочу, чтобы параметром передавалось имя файла, для дальнейшего его использования функцией fopen. что делать?


Все переданные аргументы ты найдешь в массиве argv. в переменной argc будет их количество
первый аргумент - всегда имя запускаемой программы

то есть при такой командной строке

c:\bin\zzz.exe file.txt "1 2 3"

argc = 3
argv[0] = "c:\bin\zzz.exe"
argv[1] = "file.txt"
argv[2] = "1 2 3"

имя файла можно открыть функций _tfopen

вопрос 2-й
вообще я хочу из файла занести данные в двумерный массив. в задаче сказано: "Пустая клетка представлена символом '.', закрашенная - символом '#'. Число строк и столбцов не превышает 500.". я так понимаю, что это означает, что мне придётся использовать массив 500х500. и я погуглил всякие тексты, но пока так толком и не понял: как мне эти данные занести в массив?


например завести массив
unsigned char map[500][500] = {{0}};

дальше считывать туда посимвольно или сразу строками - зависит от формата данных
Rififi вне форума Ответить с цитированием
Старый 03.03.2013, 14:10   #4
ya2500
Пользователь
 
Регистрация: 03.03.2013
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Если не ошибаюсь то fopen(argv[1]...) писать будешь.
пишу file = fopen(argv[1], "w");
ошибка:
error C2664: fopen: невозможно преобразовать параметр 1 из '_TCHAR *' в 'const char *'

потому и спрашиваю.

Цитата:
Сообщение от Rififi Посмотреть сообщение
имя файла можно открыть функций _tfopen
пишу file = _tfopen(argv[1], _T("w"));
работает,
но есть предупреждение о том, что эта функция не безопасна. так же как и функция _wfopen- её тоже пробовал. в-общем, всё в порядке, не считая одного варнинга.

итого: большое спасибо, теперь понятно, как брать файл из параметров командной строки.
ya2500 вне форума Ответить с цитированием
Старый 03.03.2013, 14:51   #5
ya2500
Пользователь
 
Регистрация: 03.03.2013
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
argv[1] даст тебе указатель на имя файла. Если не ошибаюсь то fopen(argv[1]...) писать будешь.

Как выглядят данные в файле?
я пытаюсь самостоятельно решить следующую задачу:

Цитата:
Дан клетчатый лист бумаги, в котором некоторые клетки закрашены. Требуется найти кратчайший путь из левой верхней клетки в правую нижнюю. Двигаться можно только по вертикали или горизонтали.

Исходные данные: Пустая клетка представлена символом '.', закрашенная - символом '#'. Число строк и столбцов не превышает 500.

Результат: Такое же представление лабиринта, в котором найденный путь изображен символом '*'

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

генерация "лабиринта" готова и выглядит так:
Код:
// Maze_Gen.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <stdlib.h> // для функции rand()
#include <time.h> // для функции time

int _tmain(int argc, _TCHAR* argv[])
{
	if (argc == 2) // прога обязательно должна иметь один параметр
	{
		FILE *file;

		file = _tfopen(argv[1], _T("w")); // открываем файл для записи
		// w- write, r- read, a- append

		//инициализация генератора псевдослучайных чисел значением текущего времени
		srand((unsigned long)time(NULL));

		// случайное количество столбцов и строк x и y:
		int x = rand()%50+1, y = rand()%50+1, r; 
	
		for (int i=1; i<=y; i++)
		{
			for (int j=1; j<=x; j++)
			{
				r = rand()%6; // 0..5
				
				// идём слева-сверху в право-вниз
				// первый и последний символ пути должен быть точкой:
				if ((r==0)&&((i<y)||(j<x))&&((j>1)||(i>1))) fputc('#',file);
				else fputc('.',file);
			}
			fputc('\n',file); // перевожу строку
			// fputc, fputs, fgetc, fgets, fprintf, fscanf
		}
	}

	return 0;
}

Последний раз редактировалось Stilet; 05.03.2013 в 09:24.
ya2500 вне форума Ответить с цитированием
Старый 05.03.2013, 08:31   #6
ya2500
Пользователь
 
Регистрация: 03.03.2013
Сообщений: 12
По умолчанию

С алгоритмом давно уже определился:
Цитата:
Поместить начальную клетку в очередь.
Пометить начальную клетку числом 0.
Пока очередь не пуста, повторять:
- достать очередную клетку i из очереди.
- всех соседей j клетки i, которые ещё не были в очереди, пометить числом, на единицу большим, чем число в клетке i и затолкать их тоже в очередь.

так мы найдём расстояние до выхода. им будет помечена клетка выхода. так же как остальные клетки помечены расстояниями от входа до них.

Как вывести при этом маршрут? Нетрудно: когда заталкиваем соседа j клетки i в очередь, отмечаем pi[j]=i, а потом двигаемся по массиву pi от финальной клетки в начальную (в обратном порядке).
Осталось сделать решительный рывок, и всё это правильно закодить.

Последний раз редактировалось ya2500; 05.03.2013 в 13:37.
ya2500 вне форума Ответить с цитированием
Старый 05.03.2013, 09:26   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Ясно. Увы я лично с алгоритмами не дружу.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 05.03.2013, 09:38   #8
ya2500
Пользователь
 
Регистрация: 03.03.2013
Сообщений: 12
По умолчанию

ПРОБЛЕМА:

лабиринт генерится программой, приведённой выше. пытаюсь его считать и возникает какая-то "неустранимая ошибка" и Программа "[632] Maze_Path.exe: Машинный код" завершилась с кодом -1073740777 (0xc0000417). вот эта программа, считывающая массив:
Код:
// Maze_Path.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{	

	// *** получаем лабиринт из файла: начало

	FILE *file;
	char *input_name= "input.txt", *output_name= "output.txt";
	unsigned char Maze[50][50] = {{0}}, c;

	// инициализируем массив символами '0'(ноль):
	for (int i=0; i<50; i++)
		for (int j=0; j<50; j++)
			Maze[j][i] = '0';

	file = fopen(input_name, "r"); // открываем файл для чтения
	// w- write, r- read, a- append

	int x= 0, y= 0; // столбцы и строки

	do {
		c = fgetc(file);
		// fputc, fputs, fgetc, fgets, fprintf, fscanf
		if ((c == '.') || (c == '#'))
		{
			Maze[x][y]= c;
			x++;
		}
		else
			if (c == '\n')
			{
				y++;
				x = 0;
			}
	} while (c != EOF);

	// *** получаем лабиринт из файла: конец

	return 0;
}
ошибка где-то в цикле do..while, так как, если его закомментить, то всё работает нормально. файл input.txt лежит в той же папке, что и экзешник этой проги.

если запустить прогу не из среды, а непосредственно экзешник, то висит чёрное окошко и не убирается. ошибку не выдаёт.

Последний раз редактировалось ya2500; 05.03.2013 в 10:10.
ya2500 вне форума Ответить с цитированием
Старый 05.03.2013, 11:33   #9
ya2500
Пользователь
 
Регистрация: 03.03.2013
Сообщений: 12
По умолчанию

добавил строку
if (file == NULL) return -1;
после fopen,
кое-что изменилось:

теперь, будучи запущенной из среды, прога выдаёт -1. то есть, она не находит файл. скопировал input.txt и к файлам проги, и теперь, будучи запущенной из среды, прога тоже выдаёт чёрное окошко, которое не убирается. программа не завершается. такая вот мелкая доп инфа о том, где VC++ ищет файлы.
ya2500 вне форума Ответить с цитированием
Старый 05.03.2013, 12:36   #10
ya2500
Пользователь
 
Регистрация: 03.03.2013
Сообщений: 12
По умолчанию

разобрался. я позаимствовал из интернета не верную проверку конца файла, из-за чего цикл do ... while не мог завершиться.

исправил. теперь моя прога умеет считывать лабиринт из файла и записывать его в файл:
Код:
// Maze_Path.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <memory.h> // для memset


int _tmain(int argc, _TCHAR* argv[])
{	

	// *** получаем лабиринт из файла: начало

	FILE *file;
	char *input_name= "input.txt", *output_name= "output.txt";
	unsigned char Maze[50][50] = {{0}}, c;

	// инициализируем массив символами '0'(ноль):
	memset(Maze, '0', sizeof(Maze));

	file = fopen(input_name, "r"); // открываем файл для чтения
	// w- write, r- read, a- append
	
	if (file == NULL) return -1;

	int x= 0, y= 0; // столбцы и строки

	do {
		c = fgetc(file);
		// fputc, fputs, fgetc, fgets, fprintf, fscanf
		if ((c == '.') || (c == '#'))
		{
			Maze[x][y]= c;
			x++;
		}
		else
			if (c == '\n')
			{
				y++;
				x = 0;
			}
	} while (!feof(file));

	fclose(file);

	// *** получаем лабиринт из файла: конец

	// *** выводим лабиринт в файл: начало

	file = fopen(output_name, "w"); // открываем файл для записи

	for (int i=0; i<50; i++)
	{
		for (int j=0; j<50; j++)
		{
			fputc(Maze[j][i],file);
		}
		fputc('\n',file); // перевожу строку
	}	

	fclose(file);

	// *** выводим лабиринт в файл: конец

	return 0;
}
можно было бы работать с динамическим массивом, но это как-нибудь в другой раз.
ya2500 вне форума Ответить с цитированием
Ответ


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

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
пытаюсь разобраться с pipe, (linux,c++) Egyptorium Общие вопросы C/C++ 4 10.01.2013 02:12
Пытаюсь разобраться с API сайта (php+xml+soap) woulf PHP 0 17.12.2012 03:05
пытаюсь разобраться Кудаив Помощь студентам 6 01.05.2012 23:04
Пытаюсь разобраться в принципах куки! Steh JavaScript, Ajax 2 02.02.2010 13:03
Пытаюсь разобраться в задании fs444 Microsoft Office Excel 12 12.01.2010 12:57