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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.05.2012, 18:51   #1
StayCool
Пользователь
 
Регистрация: 25.11.2011
Сообщений: 12
По умолчанию Потоки С++

Задача: открыть файл в двоичном виде и записать в массив, для того что бы отредактировать. Я до этого никогда не встречался с потоками. Удобно ли будет хранить файл размером 2 мегабайта в массиве? Объявлять надо long long?

Код:
Код:
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <conio.h>
#include <stdio.h>
using namespace std;

int main()
{
   FILE * pFile;
   char buffer [100];

   pFile = fopen ("file.wav" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else
   {
     while ( ! feof (pFile) )
     {
       if ( fgets (buffer , 100 , pFile) != NULL )
         fputs (buffer , stdout);
     }
     fclose (pFile);
   }
   getchar();
   return 0;
}
P.S. это для текстового файла. Переделать под любой тип файла/считывание в двоичном виде не получилось.
StayCool вне форума Ответить с цитированием
Старый 04.05.2012, 00:27   #2
datMaster
Пользователь
 
Регистрация: 30.08.2011
Сообщений: 20
По умолчанию

зачем файл переписывать в массив а потом редактировать, если к бинарному файлу можно обращаться произвольно на прямую?
datMaster вне форума Ответить с цитированием
Старый 04.05.2012, 07:55   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
открыть файл в двоичном виде и записать в массив, для того что бы отредактировать.
Каков характер редактирования? Если ты будешь оперировать с данными сложными тормознутыми алгоритмами то да - однозначно считать файл в память (или хотя бы оперировать поблочно).
Цитата:
Переделать под любой тип файла/считывание в двоичном виде не получилось.
Думаю стоит заменить твой цикл считки на считку в динмассив, размером с размер файла. http://www.programmersforum.ru/showthread.php?t=59088
Только тут пожалуй стоит используя функцию получения размера файла зарезервировать не 20 как в примере а по полной память для считки всего файла целиком. 2Мб это еще не так много.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.05.2012, 16:06   #4
StayCool
Пользователь
 
Регистрация: 25.11.2011
Сообщений: 12
По умолчанию

Характер редактирования: изменить бит №164 на 0, бит №172 на 1, бит №180 на 1 и еще несколько десятков. Это можно сделать напрямую?
Как указать определённый бит?
StayCool вне форума Ответить с цитированием
Старый 06.05.2012, 16:51   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Считай весь файл в массив, в массиве изменяй нужные байты, и после изменения записывай все.
Или: Открываешь файл как binary, становишся на позицию 164/8, считываешь символ, меняешь в нем биты, перемещаешся на позицию в файле назад, записываешь измененный байт.

Я имею ввиду вот такое:
Код:
	FILE* f=fopen("d:\\q.xml","rw");
	fseek(f,0,SEEK_END);
	int i=ftell(f);
    char* s=new char[i];
	fseek(f,0,SEEK_SET);
	fread(s,1,i,f);
	s[164/8]&=0xFF;
	fseek(f,0,SEEK_SET);
	fwrite(s,1,i,f);
	fclose(f);
	delete s;
I'm learning to live...

Последний раз редактировалось Stilet; 06.05.2012 в 17:01.
Stilet вне форума Ответить с цитированием
Старый 06.05.2012, 17:57   #6
StayCool
Пользователь
 
Регистрация: 25.11.2011
Сообщений: 12
По умолчанию

Stilet
Виталик! Мой файл формата wave. Разве нельзя открыть его в двоичном виде, побитово, что в любой ячейке массива были только нули и единицы?

P.S. я тебе стукнул в аську
StayCool вне форума Ответить с цитированием
Старый 06.05.2012, 18:04   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Разве нельзя открыть его в двоичном виде, побитово
Побитово может только гопник с битой сделать
Байт - атомарная единица данных
Считывй побайтно, и битовыми масками меняй его.
Цитата:
я тебе стукнул в аську
Бесполезно - файер гасит ее, я вообще отключил.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 07.05.2012, 00:15   #8
StayCool
Пользователь
 
Регистрация: 25.11.2011
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Байт - атомарная единица данных
это как? 1 byte = 8 bit
P.S. не понимаю что такое битовые маски. Можешь объяснить?

Код:
#include <stdio.h>
#include <stdlib.h>
#include "stdafx.h"
#include <iostream>

int main () {
	char text[]="01001001010011110101011000100000001100110010111000110
001001101000010000001001101001110100100100100100000010101
0001000010010011010100011001000101";
	FILE * pFile;
	long lSize;
	int l=0,i=0,c=0;
	char * buffer;
	size_t result;
	pFile = fopen ( "1.txt" , "r+b" );
		if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

// получение размера файла:
	fseek (pFile , 0 , SEEK_END);
	lSize = ftell (pFile);
	rewind (pFile);

// выделение памяти что бы разместить весь файл:
	buffer = (char*) malloc (sizeof(char)*lSize);
	if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

// копирование файла в buffer:
	result = fread (buffer,1,lSize,pFile);
	if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

	/* Теперь весь файл загружен в buffer */
	for (i=0;i<lSize;i++)
		c++;

// удаление всех пробелов из buffer:
	for (i=0;i<lSize;i++)
		{
			if (buffer[i]==' ')
				{
					for (int j=i;j<lSize;j++)
						buffer[j]=buffer[j+1];
						lSize-=1;
				}
		}
	int o=0;
	for (i=0;i<lSize;i++)
	  o++;

	int n=0,k=0,h=0;

// вывод каждого восьмого числа на экран перед изменением:
	std::cout<<"How it was: "<<std::endl;
	for (k=7;k<(sizeof(text)*8);k+=8)
		std::cout<<buffer[k];

// изменение каждого восьмого числа:
	for (k=7;k<(sizeof(text)*8);k+=8)
	    {
			buffer[k]=text[n];
			n++;
		}
	std::cout<<std::endl;

// вывод каждого восьмого числа на экран после изменения:
	std::cout<<"How it is: "<<std::endl;
	for (k=7;k<(sizeof(text)*8);k+=8)
		{
			std::cout<<buffer[k];
			l++;
		}
	
// проверочные значения:
	std::cout<<std::endl<<"Before deleting spaces: "<<c<<std::endl<<"After deleting spaces: ";
	std::cout<<o<<std::endl<<"Could be changed: "<<o/217<<std::endl<<"Changed: "<<l;
	std::cout<<std::endl<<"Size of text: "<<sizeof(text);

	fclose(pFile);
        pFile = fopen ( "new1.bin" , "wb" );
        fwrite (buffer , 23300 , sizeof(buffer) , pFile );
        getchar();
        fclose(pFile);
	free (buffer);
	return 0;
}
То, что записывается в файл new1.bin и массив buffer - отличаются. В чём проблема?

P.S. Почему-то не могу переделать код что бы считывался любой файл в бинарном виде. =( приходится брать txt с единицами и нулями внутри.

Последний раз редактировалось Stilet; 07.05.2012 в 07:57.
StayCool вне форума Ответить с цитированием
Старый 07.05.2012, 00:45   #9
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Код:
	char x = 0; // вот байт
	
	//скажем, шестой бит надо установить в 1
	x |= 1 << 5; // индекс с нуля, начиная с младшего бита
	
	// или так
	x = x | 0x20;
	
	//проверить установлен ли он
	if (x & 1 << 5)	{}
	
	// или так
	if (x & 0x20) {}
	
	//снять бит
	x &= ~0x20;
Не понимаю, для чего нужно строковое представление ноликов-единичек....
EUGY вне форума Ответить с цитированием
Старый 07.05.2012, 08:00   #10
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Можешь объяснить?
EUGY объяснил. Его примеры операций с битовыми масками (0x20 например маска - число указывающее с какими битами работать на основании бит этого числа).
А вот в строку биты переводить - лишнее.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
потоки MetR Помощь студентам 0 11.12.2011 19:07
потоки AlexMe Общие вопросы Delphi 3 18.07.2011 05:17
Потоки Florento Общие вопросы Delphi 4 17.06.2011 16:16
потоки tanek Помощь студентам 6 15.03.2010 21:42
Потоки в С++ BioS Общие вопросы C/C++ 2 09.01.2010 21:34