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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 28.06.2016, 18:57   #1
Narsky
Форумчанин
 
Регистрация: 21.06.2016
Сообщений: 109
По умолчанию Файлы, строки и динамическая память С++

1. Нужна помощь в написании программы, с файлами совсем не дружу, буду рад сотрудничать)
Задача:
Цитата:
Изменение данных в файле.
Записать в текстовый файл ряд целых чисел 0, 1, 2…N, затем M раз случайным образом заменить элементы на -1. Числа N, M вводятся пользователем.

Примечание: Результат работы с данными вывести на экран и в новый файл. Файл с входными данными имеет название INPUT.TXT для текстовых файлов и INPUT.DAT для двоичных. Файл, в который записывается результат, называется OUTPUT.TXT для текстовых файлов или OUTPUT.DAT для двоичных. Для создания файлов с исходными данными можно использовать различные утилиты (например, Binary Viewer). Число элементов при считывании файла определяется его длиной, либо, если этого не определяет алгоритм, двумя сотнями (200). Лучшими решениями считаются те, где нет привязки к количеству элементов в файле. При необходимости можно использовать временный файл для хранения промежуточных результатов.
2. То же самое и со строками, но часть кода я уже написал (и то может быть неправильно), нужна помощь.
Со строками мало работал, понимаю лишь, что в функции del нужно с помощью циклов найти эти два символа, а затем опять же с помощью цикла удалить все символы между ними. Но вот как это все организовать, понять не могу)
Цитата:
Удаление символов Написать функцию, обеспечивающую ввод с клавиатуры строки неограниченной длины без редактирования. Написать функцию, которая удаляет символы, стоящие между двумя определенными символами. Символ вводится пользователем.

Примечание: В каждой задаче должна быть реализована проверка на целостность кучи. При работе со строками учитывать символ конца строки (байт с нулевым значением).
Заполнение элементов массива (там, где это требуется) должно быть реализовано в виде отдельной функции. В этой функции запрашивается количество элементов массива, затем пользователю предоставляется выбор – либо вводить массив с клавиатуры, либо заполнить его автоматически (случайными числами).
В случаях, когда функция сама формирует массив, она должна посредством своих аргументов (объявленных как указатели) передать в вызывающую программу новый массив и число его элементов. Возвращаемое функцией число должно означать код ошибки (например, 0 – нет ошибки, ненулевое число – код конкретной ошибки). Во всех задачах, где необходимо вводить строки (не)ограниченной длины без редактирования, следует иметь в виду, что для хранения строки необходимо использовать динамическую память. Размер блока, выделенного под строку, увеличивается при вводе очередного символа. Строка генерируется внутри функции ввода. Функция возвращает указатель на начало строки. Ввод строки завершается при нажатии клавиши Enter, код Enter в строке не сохраняется.
Если на каком-либо этапе память выделить невозможно, то необходимо освободить всю выделенную ранее память и завершить программу. Особое внимание уделить обработке различных ошибок – при их возникновении необходимо освобождать все ставшие ненужными ресурсы. При формировании нового массива можно реализовать любой из следующих алгоритмов, либо разработать свой: 1) создать новый массив и перенести в него нужные элементы. 2) скопировать исходный массив и поэлементно его изменять (например, переставлять элементы).
Цитата:
#include <iostream>
#include <string>
using namespace std;

void del(string str)
{
}

int main()
{
setlocale(LC_ALL, "Russian");

cout << "Введите текст" << endl;
string str;
getline(cin, str);
cout << "Результат: " << str << endl;

char a, b;
cout << "Введите 1 символ" << endl;
cin >> a;
cout << "Введите 2 символ" << endl;
cin >> b;

del(str);
system("pause");
return 0;
}
3. Программа с динамическим выделением памяти.
Программа не работает, если не было введено ни одного отрицательного числа. Есть подозрение на то, что что-то не так написано в void summa (нет варианта, если нет ни одного отрицательного числа), не могли бы вы посмотреть?
Цитата:
С одномерным динамическим массивом, состоящим из n вещественных элементов, произвести следующие операции:
1) вычислить сумму отрицательных элементов массива;
2) вычислить произведение элементов массива, расположенных между максимальным и минимальным элементами. При наличии нескольких максимальных или минимальных элементов (равных друг другу) выбираются первые из них;
3) упорядочить элементы массива по возрастанию.

Примечание: Размеры массивов и значения элементов вводятся пользователем. Все операции над массивами выполняются отдельными функциями в том порядке, в котором они описаны в задании. В каждой задаче необходимо предусмотреть функцию ввода с клавиатуры одномерного массива. Кроме того, в каждой задаче должна быть реализована проверка на целостность кучи (см. приложение 2).
Цитата:
/*С одномерным динамическим массивом, состоящим из n вещественных элементов, произвести следующие операции:
1) вычислить сумму отрицательных элементов массива;
2) вычислить произведение элементов массива, расположенных между максимальным и минимальным элементами. При наличии нескольких максимальных или минимальных элементов (равных друг другу) выбираются первые из них;
3) упорядочить элементы массива по возрастанию.
*/
#include <iostream>
#include <algorithm>
using namespace std;

void summa(int a, double b[])
{
double sum = 0;
for (int i = 0; i < a; i++)
{
if (b[i] < 0)
{
sum = sum + b[i];
}
}
cout << "Сумма отрицательных элементов массива: " << sum;
}

void proiz (int a, double b[])
{
double max = 0, min = 0;
int max_i, min_i;
for (int i = 0; i < a; i++)
{
if (b[i] > max)
{
max = b[i];
max_i = i;
}
}
for (int i = 0; i < a; i++)
{
if (b[i] < min)
{
min = b[i];
min_i = i;
}
}
double mul = 1;
for( int i = std::min(max_i , min_i) ; i < std::max(max_i , min_i); ++i )
{
mul *= b[i];
}
cout << "Произведение элементов массива, расположенных между максимальным и минимальным элементами равно: " << mul << endl;
}

void poryadok (int a, double b[])
{
for (int j = 0; j < a - 1; j++)
{
int i, k;
k = j;
for (i = j + 1; i < a; i++)
if (b[i] < b[k])
k = i;
double buf = b[j];
b[j] = b[k];
b[k] = buf;
}
for (int i = 0; i < a; i++)
cout << b[i] << endl;
}


int main(){
int a;
setlocale(LC_ALL, "Russian");
cout << "Введите размер массива: " << endl;
cin >> a;
if (a < 1) cout << "Ошибка! Введен неверный размер массива" << endl;
else
{
double *b = new double[a];

for (int i = 0; i < a; i++)
{
cout << "Введите " << i + 1 << " элемент массива" << endl;
cin >> b[i];
}

cout << "Ваш массив:" << endl;
for (int i = 0; i < a; i++)
{
cout << b[i] << " ";
}

summa(a, b);
proiz(a, b);
poryadok(a, b);

delete(b);
system("pause");
}
return 0;
}

Последний раз редактировалось Narsky; 28.06.2016 в 18:59.
Narsky вне форума Ответить с цитированием
Старый 28.06.2016, 19:10   #2
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

Держи программу. Файлы ввода 1.txt, 2.txt и вывода 3.txt должны быть на диске C:/
Поигравшись с программой, подстрой её под свои условия. Будь внимательным - здесь речь идет только о *.txt


Код:
#include <fstream>
#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
	char a1[15], a2[15];

	fstream in1("C:/1.txt", ios_base::in); //	Открытие 1-го файла
	fstream in2("C:/2.txt", ios_base::in); //	Открытие 2-го файла
	ofstream out("C:/3.txt");              //	Открытие 3-го файла (для записи результата)

	if ((!in1.is_open()) || (!in2.is_open()) || (!out.is_open()))  // Проверка открылись ли все файлы
		cout << "Ошибка чтения файла\n\n\n";
	else
	{
		for (; in1.peek() != EOF;)
		{
			in1.getline(a1, 15);
			in2.getline(a2, 15);

			out << (atof(a1) + atof(a2)) / 2 << endl;                     // Запись в файл №3

		}
		in1.close();
		in2.close();
		out.close();	
	}
	system("pause");
	return 0;
}


ura_111 вне форума Ответить с цитированием
Старый 28.06.2016, 19:21   #3
Narsky
Форумчанин
 
Регистрация: 21.06.2016
Сообщений: 109
По умолчанию

Благодарю!
А возможно ли работать с файлами, создавая их непосредственно в самой программе, заполнять их данными согласно условию задачи и работать с ними?
Narsky вне форума Ответить с цитированием
Старый 28.06.2016, 19:35   #4
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

В смысле?
1) В моём примере файлы для чтения и записи уже созданы на диске, но если нужно создать новый файл в процессе работы программы, то





Подробнее здесь:

http://cppstudio.com/post/446/


2) Или речь ишла про то, чтобы работать с файлом в любом месте программы (в функции например).
- Работать с файлом можно везде, где есть ключевая конструкция:


fstream in1("C:/1.txt", ios_base::in); // Открытие 1-го файла для чтения
{
какие-то манипуляции с данными
}
in1.close(); // закрытие файла

Обрати внимание на флаг ios_base::in (посмотри на картинку).

Последний раз редактировалось ura_111; 28.06.2016 в 19:38.
ura_111 вне форума Ответить с цитированием
Старый 28.06.2016, 19:43   #5
Narsky
Форумчанин
 
Регистрация: 21.06.2016
Сообщений: 109
По умолчанию

Вот смотри, у меня есть программа, наподобие которой мне нужно сделать свою, только на С++.
Цитата:
Копировщик файлов. Написать программу, которая копирует содержимое одного файла в другой.

Примечание: Результат работы с данными вывести на экран и в новый файл. Файл с входными данными имеет название INPUT.TXT для текстовых файлов и INPUT.DAT для двоичных. Файл, в который записывается результат, называется OUTPUT.TXT для текстовых файлов или OUTPUT.DAT для двоичных. Для создания файлов с исходными данными можно использовать различные утилиты (например, Binary Viewer). Число элементов при считывании файла определяется его длиной, либо, если этого не определяет алгоритм, двумя сотнями (200). Лучшими решениями считаются те, где нет привязки к количеству элементов в файле. При необходимости можно использовать временный файл для хранения промежуточных результатов.
Цитата:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <conio.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>


int main()
{
FILE *file1, *file2;
char *fname1 = "INPUT.dat";
char *fname2 = "OUTPUT.dat";
int S, i;
setlocale(0, "rus");

file1 = fopen(fname1, "wb");

srand(time(NULL));
for (i = 0; i < 13; i++)
{
S = 70 + 2;
printf("%d ",S);
fwrite(&S, sizeof(int), 1, file1);

}

fclose(file1);

file1 = fopen(fname2, "rb");
file2 = fopen(fname2, "wb");
fseek(file1, 0, SEEK_SET);
for (i = 0; i < 13; i++)
{
fread(&S, sizeof(int), 1, file1);
printf("%d ",S);
fwrite(&S, sizeof(int), 1, file2);
}

fclose(file1);
fclose(file2);

printf("Я ВСЕ! Для выхода нажми любую клавишу...");

if (! _getch()) _getch();
return 0;
}
Здесь не надо создавать никаких файлов заранее.
Narsky вне форума Ответить с цитированием
Старый 28.06.2016, 20:06   #6
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

Как? Не надо создавать заранее файлы?

По крайней мере нужен 1 файл (откуда берутся данные для расчета), созданный заранее. Вдумайся в слова:

"...Файл с входными данными имеет название INPUT.TXT... Для создания файлов с исходными данными можно использовать различные утилиты...".
ura_111 вне форума Ответить с цитированием
Старый 28.06.2016, 20:24   #7
Narsky
Форумчанин
 
Регистрация: 21.06.2016
Сообщений: 109
По умолчанию

Ты уверен? Просто в программе, которую я скинул, как я понимаю, сначала объявляется файл, а затем заполняется данными с помощью функции...
В моей задаче также, мне кажется, нужно создать файл с помощью программы, ввести числа N и M, которые и определят данные, которые должны быть в остальных файлах?
Цитата:
Записать в текстовый файл ряд целых чисел 0, 1, 2…N, затем M раз случайным образом заменить элементы на -1. Числа N, M вводятся пользователем.
Narsky вне форума Ответить с цитированием
Старый 28.06.2016, 21:15   #8
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

Похоже ты прав. Вот набросал. Поиграйся с программой.

Код:
#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>
using namespace std;

int main()
{
	setlocale(0, "rus");

	FILE *file1;
	char *fname1 = "INPUT.txt";

	int S[200];	
	for (int i = 0; i < 200; i++)
	{
		S[i] = 0;
	}
	
	int N, M;
	cout << "Введите N: ";
	cin >> N;
	cout << "Введите M: ";
	cin >> M;
	
	// Запись в файл
	file1 = fopen(fname1, "wb");
	for (int i = 0; i < N; i++)
	{
		fwrite(&i, sizeof(int), 1, file1);
	}
	fclose(file1);
	/////////////////
			
	// Чтение из файла и вывод на экран		
	printf("\nЧтение из файла:\n");
	file1 = fopen(fname1, "rb");
	fseek(file1, 0, SEEK_SET);
	for (int i = 0; i < N; i++)
	{
		fread(&S[i], sizeof(int), 1, file1);
		printf("%d ", S[i]);
	}	
	fclose(file1);	
	///////////////////////////////////

	// Замена на значений -1
	srand(time(NULL));



	printf("\n\nЯ ВСЕ!  Для выхода нажми любую клавишу...");
	if (!_getch()) _getch();
	return 0;
}








Вот, что тебе надо сделать?
В текст программы вставить свою вырезку, которая "случайно заменяет" элементы S[] на -1 М-раз и запись в файл

while(M>0)
{
for(....)
{
.......
}
M--;
}
А теперь запись S[] в файл и проверка (чтение и вывод) что записало.






Последний раз редактировалось ura_111; 28.06.2016 в 21:29.
ura_111 вне форума Ответить с цитированием
Старый 28.06.2016, 21:19   #9
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

И учти, что когда ты сделаешь мной выше написанное - то ты сделаешь только половину своего задания - ведь тебе нужно еще показать работу с *bat файлом.

Может быть лучше сделать небольшое меню, где пользователь будет выберать с каким типом файла он хотел бы работать .

Или в примечании написано для общего случая, а тебе надо только *.txt

Последний раз редактировалось ura_111; 28.06.2016 в 21:30.
ura_111 вне форума Ответить с цитированием
Старый 28.06.2016, 21:28   #10
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

И ещё одно. Будь осторожен - уточни для себя как нужно представить информацию в файле INPUT.txt? Т.е.

Вот так
0
1
2
3
4
.....

Или в двоичном (как у тебя в примере). См. "закарлючки" у меня на рисунке выше, когда я открыл файл INPUT.txt, чтобы посмотреть что там.

Напомню. флаг "wb" - Создает двоичный файл для записи.
ura_111 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамическая память dykee Помощь студентам 2 27.02.2014 01:52
Динамическая память. spotmc13 Паскаль, Turbo Pascal, PascalABC.NET 5 20.09.2010 17:08
Динамическая память PaulSev Общие вопросы Delphi 12 25.03.2010 09:07
динамическая память zhenya.ya Помощь студентам 2 24.02.2010 20:58
динамическая память aka_faith Общие вопросы C/C++ 47 12.06.2009 12:35