Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по программированию на C/С++

Автор: Dayver2009
Дата сообщения: 15.11.2006 19:16
Люди Хелп!!!
Есть такая задача На С++ Билдер

Нужно открыть файл (например текстовый .тхт) и разбить его на блоки по 256 символов
далее берем один блок(например первый) и заносим ASCII двоичный код каждого символа в вектор T[2048]

Схема
T[2048]={ {0,1,0,0,1,1,1,1},{0,1,1,0,1,0,1,1}, {0,1,1,0,1,1,0,0}, .... ,{0,1,1,0,0,0,1,0}}; (Пример)


T[2048]={8 бит 1-го символа,8 бит 2-го символа,8 бит 3-го символа,....,8 бит 32 символа}; (Пояснение структуры)

2 недели бюсь над етим, искал в разной литературе ничего подобного.
Автор: abrakadabra13
Дата сообщения: 16.11.2006 00:32
Mickey_from_nsk, на ваш код ругается компилятор: "error C2440: 'initializing' : cannot convert from 'int**' to 'int *' "
Что с этим делать?
Автор: Mickey_from_nsk
Дата сообщения: 16.11.2006 08:30
abrakadabra13
Замени
int *array[] ...
на
int **array ...
Все собралось.
Автор: Mickey_from_nsk
Дата сообщения: 16.11.2006 12:12
Dayver2009
А ты сам все понял, что надо сделать? Что значит
Цитата:
берем один блок(например первый)
для файла. Где у него право, а где лево?
Теперь по тексту примера.
Насколько я понял самая большая трудность для тебя разложить байт в поток нулей и единиц? Или как?
Какого типа элемент вектора Т?
может такая функция поможет?

Код:
void toDigits(byte theByte, int [] res)
{
memset(res, 0, sizeof(res[0])*8);
for (int i=0, byte mask = 1<<7; i<8; i++)
{
if (mask & theByte)
res[i] = 1;
else
res[i] = 0;
mask >>= 1;
}
}
Автор: Dayver2009
Дата сообщения: 16.11.2006 21:02
Mickey_from_nsk

Цитата:для файла. Где у него право, а где лево?

Не знаю где у файла право, а где лево но начало у файла должно же быть. Вот и начинаем с начала файла . А разбивка файла на блоки осуществляется по рядкам начиная с первого рядка и далее вниз(тоесть если первый рядок текст. фала содержыт 256 символов, включая символ переноса строки, то ето и будет первый блок,а если файл имеет например одну строку из 536 символов то файл разделится на 3 блока, 2 блока по 256 символов и 1 блок с 24 сиволами).

Цитата:Какого типа элемент вектора Т?

Тип елементов вектора Т - int, но можно и bool.(Если ето имеет важное значение)

Цитата:самая большая трудность для тебя

Для меня трудность - написать программный код который выполнял бы по очереди такие действия:
1)Открывал файл(Загружал его в какойто буфер или что то вроде етого)
2)Далее из етого буфера заполнял бы ячейки вектора Т не буквами,цыфрами или другими знаками, а именно ихними двоичными кодами ASCII(Например буква W - десятичная цыфра 87 или двоичная 01010111).

Цитата:разложить байт в поток нулей и единиц?

Поетому байты нужно раскладывать не в поток, а именно в вектор Т
(Если первой буква блока - "W" , то вектор будет выглядеть так Т[2048]={0,1,0,1,0,1,1,1,....................................};

Может я не коректно обясняю суть проблемы?Вы уж извените студента который только начинает изучать язык С++
Автор: abrakadabra13
Дата сообщения: 17.11.2006 01:06
Mickey_from_nsk, ссори за тупняк
не шарю просто
теперь вроде всё работает!
Автор: Mickey_from_nsk
Дата сообщения: 17.11.2006 13:08
Dayver2009

Цитата:
Не знаю где у файла право, а где лево но начало у файла должно же быть

Извини. После полубессонной ночи прочитал "первый" как "правый" .

Цитата:
Для меня трудность - написать программный код который выполнял бы по очереди такие действия:
1)Открывал файл(Загружал его в какойто буфер или что то вроде етого)
2)Далее из етого буфера заполнял бы ячейки вектора Т не буквами,цыфрами или другими знаками, а именно ихними двоичными кодами ASCII(Например буква W - десятичная цыфра 87 или двоичная 01010111).

1)

Код:
int handle = open("filename.txt", O_RDONLY);
Автор: Qraizer
Дата сообщения: 17.11.2006 13:56
Dayver2009
Код: #include <fstream>
#include <bitset>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <functional>

int main()
{
std::ifstream inFile ("input.txt", std::ios::binary);
std::ofstream outFile("output.txt");
std::vector<bool> T (2048);
std::vector<char> buf(256);

do
{
std::streamsize count = inFile.read(&buf[0], buf.size()).gcount();

if(count==0) break;
for(int i=0; i<count; ++i)
{
std::string tmp(std::bitset<8>(buf[i]).to_string<
char, std::char_traits<char>, std::allocator<char>
>());
std::transform(tmp.begin(), tmp.end(), T.begin()+i*8, std::bind2nd(std::equal_to<char>(), '\x31'));
}
std::copy(T.begin(), T.begin()+count*8, std::ostream_iterator<bool>(outFile));
*std::ostream_iterator<char>(outFile)++ = '\n';
} while(inFile.good());
}
Автор: DoctorLans
Дата сообщения: 17.11.2006 19:10
Люди, ищу функции для работы с консолью в Visual C++ (перемещение курсора на произвольное место, очистка консоли и т.д.).

И второе, ищу справочную информацию по свежему winAPI (то бишь по windows XP) в C++ на родном и могучем.

Ну и третье, вот задумался я, что же все таки храниться в .obj файлах, создаваемых при компиляции программ?
Автор: Dayver2009
Дата сообщения: 17.11.2006 20:14
Qraizer

Спасибо!Разобрался. Работает как надо.

Но тогда не понятно как произвести обратное действие - из вектрора поочередно извлекать по 8 ячеек, преобразовывать двоичный код(который образуется из етих 8 ячеек) в ASCII символ и записывать етот символ в файл.

Подскажы пожалуйста чем заменить строки
Цитата:
std::copy(T.begin(), T.begin()+count*8, std::ostream_iterator<bool>(outFile));
*std::ostream_iterator<char>(outFile)++ = '\n';
из преведеного тобой листинга

чтоб после математических операций которые я произведу над елементами вектора Т можно было обратно увидеть в файле "output.txt" ASCII символы, а не их двоичный код (последовательность 0 и 1).

Я просто думал что прямая задача (символы преобразуются в двоичный код и заганяются в вектор) реализуется с помощью какихто преобразований или функций и тогда я сам бы мог зделать обратную задачу (преобразование двоичного кода из вектора в сиволы и запись етих символов в файл). А здесь как я понял не каких преобразований символов в код не производится, а просто считываются из файла особым способом.

я попробывал просто изменить строчку
Цитата:
std::ofstream outFile("output.txt");

на такую std::ofstream outFile("output.txt", std::ios::binary);
но ето ничего не изменило только добавляет какойто символ-квадратик к тексту файла.
Автор: RedLord
Дата сообщения: 17.11.2006 20:19
DoctorLans

по первому - посмотри в сторону stdlib и т.д.
по второму - если дружишь с англицким - то на microsoft.com
по третьему - в obj компилятор хранит бинарный код. сpp превращается в obj
линковщик потом всю эту байду собирает. + отладочная информация для debug
подозреваю, что еще что-то
Автор: DoctorLans
Дата сообщения: 18.11.2006 07:46
RedLord
1. Спасибо, поищу на эту тему.
2. К сожалению, дружу только с русским.
3. Спасибо за пояснения.
Автор: Qraizer
Дата сообщения: 18.11.2006 19:33
stdlib - не совсем то. Скорее conio.h, но лучше всего - MSDN. Там с консолью можно сделать всё. Начни с какого-нибудь WriteConsole(), а там по ссылкам доберёшься до всего остального. Но от англицкого никуда не денешься.

Добавлено:
Dayver2009
Да что там, вот обратное преобразование
Код: #include <iostream>
#include <fstream>
#include <bitset>
#include <vector>
#include <string>

int main()
{
std::ifstream inFile ("output.txt");
std::ofstream outFile("restore.txt", std::ios::binary);
std::vector<char> buf(256);
std::string line;

do
{
std::getline(inFile, line);
if(line.length() > 2048 || (line.length() % 8) != 0)
return std::cerr << "Invalid input file format" << std::endl,
1;

for(int i=0; i<line.length()/8; ++i)
buf[i]=static_cast<char>(std::bitset<8>(line.substr(i*8, 8)).to_ulong());
outFile.write(&buf[0], line.length()/8);
} while(inFile.good());
}
Автор: JohnC
Дата сообщения: 19.11.2006 10:17
Подскажите как программно запустить "Подключение по локальной сети"
Есть для этой цели майкросовтовсая прога Cnic.exe http://www.jsifaq.com/SF/Tips/Tip.aspx?id=10930
но исходников ее я нигде не нашел.
Автор: blackdevil
Дата сообщения: 23.11.2006 22:21
Привет,люди добрые!!!Помогите новичку пож-та!Начались курсы по программированию.У меня стоит Visual Studio 2005.Пишу ну просто простейшую вещь...

#include <stdio.h>
#include <conio.h>
int main ()
{
    char val=0;
    printf(val);
    getch ();
    return 0;
}

А он (компилятор) мне в ответ что в строке с принтэфом ошибка...
error C2664: 'printf' : cannot convert parameter 1 from 'char' to 'const char *'
Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
Или я реально такой тупой и не понимаю что тут не так...или дистриб кривой?Помогите люди добрые!Проблема-то пустяковая а на ней уже нервы тратить начал...
Автор: xdude
Дата сообщения: 23.11.2006 22:28
blackdevil
Почитай MSDN, раздел по функции printf.
Первый параметр должен быть строкой, которая определяет формат выводимых данных.
Автор: blackdevil
Дата сообщения: 23.11.2006 22:31
а обычный справочник по языку сгодится?просто MSDN 3 гига занимает...места жаль (( PS спасибо огромное за совет!!!
Автор: xdude
Дата сообщения: 23.11.2006 22:36
blackdevil
Можно и обычный справочник, если в нем есть справка по функциям стандартной библиотеки C, в частности, по функции printf
Хотя, все-таки, я бы настойчиво рекомендовал MSDN, там много ненужного можно не устанавливать, и будет весить меньше гига.
Автор: Labutin
Дата сообщения: 23.11.2006 22:38
blackdevil
Или сюда можно заглянуть:
http://www.cplusplus.com/ref/cstdio/printf.html
Автор: ShurikSasha
Дата сообщения: 24.11.2006 15:51
Народ! Есть проблема со "слишком умным" линкером.
Существует следующий набор:

1. file_FactoryRegistry.h

typedef Papa * (*Factory)(void);

class FactoryRegistry {
static vector<Factory> * factory_vec;
public:
static bool addFactory( Factory f)
};

2. file_FactoryRegistry.cpp

vector<Factory> * FactoryRegistry::factory_vec = NULL;

bool FactoryRegistry::addFactory( Factory f) {
if (NULL == factory_vec )
factory_vec = new vector<Factory>();
factory_vec -> push_back(f);
}

3. file_A.h

class_A: public Papa {
public:
static Papa * factory() {return new _A(); }
};

4. file_A.cpp

bool dummy_bool_A = FactoryRegistry::addFactory( _A::factory);

5-20.
Классов, наследников от Papa, существует множество и некоторые из файлов, в которых они лежат, собираются в СТАТИЧЕСКИЕ БИБЛИОТЕКИ.

class_B: public Papa {
public:
static Papa * factory() {return new _B(); }
};

и т.д

ЯВНО экземпляры классов class_XXX нигде не создаются, а только через "factory".
ПРОБЛЕМА заключается в том, что в этом случае линкер ВООБЩЕ НЕ ВКЛЮЧАЕТ некоторые из *.cpp, собранных в СТАТИЧЕСКИЕ БИБЛИОТЕКИ, в ЕХЕшник.

Понятно, что достаточно сделать объявление типа "bool dummy_bool_A = FactoryRegistry::addFactory( _A::factory);" в модуле, который заведомо подлинковывается в ЕХЕшник ( а не в file_A.cpp, которого в ЕХЕшник не наблюдается ), то и код из file_A.cpp слинкуется и всё становится ОК.

Но не хотелось бы нарушать модульности.

Буду благодарен за КРАСИВЫЕ идеи.
Автор: Qraizer
Дата сообщения: 24.11.2006 20:22
Что значит "ВООБЩЕ НЕ ВКЛЮЧАЕТ некоторые из *.cpp, собранных в СТАТИЧЕСКИЕ БИБЛИОТЕКИ, в ЕХЕшник."? Он не может не включить, если они реально существуют в библиотеках, и к ним имеются обращения в коде. Поясни, как проявляется проблема.
Автор: Dayver2009
Дата сообщения: 25.11.2006 20:08
Qraizer

Очень благодарен за столь шырокое пояснение!
Теперь все работает в полном обеме.Даже нашел еще один
способ реализации обратной задачи.Вот его принцып

...
for(i=0;i<=2048;i=i+8)
....
void* p;
unsigned long k;
int j;
j=T[i]*128+T[i+1]*64+T[i+2]*32+T[i+3]*16+T[i+4]*8+T[i+5]*4+T[i+6]*2+T[i+7]*1;
p=CreateFile("output.txt",GENERIC_WRITE,0,0,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
SetFilePointer(p,0,0,FILE_END);
WriteFile(p,&r,1,&k,0);
CloseHandle(p);
...

Но вот пришлось улучшать интерфейс и я столкнулся с такой проблемкой
Как с помощью компонента OpenDialog изменить параметр "input.txt" в строке
std::ifstream inFile ("input.txt", std::ios::binary);
Я пытался зделать так :

AnsiString name;
if(OpenDialog1->Execute())name=OpenDialog1->FileName;
std::ifstream inFile (name , std::ios::binary);

Но выдает ошыбку :

[C++ Error] Unit1.cpp(49): E2285 Could not find a match for '_STL::ifstream::basic_ifstream(AnsiString,enum)'

как я понял то проблема в том что OpenDialog1 возвращает в переменную name Имя файла в формате "C:\C++\vxodnoi_fail.txt" , а ifstream пониает только "vxodnoi_fail.txt" в текущей папке с виполняемой программой
Хотя я могу ошыбатся

Еще раз СПАСИБО за помощь!
Автор: Arci21
Дата сообщения: 26.11.2006 11:16
Здраствуйте,подскажите пожалуйста,почему Borland C++3.1 ругается на "string" в след.программе:
-------------------------------------
#include <iostream.h>
#include <string.h>
#include <conio.h>
int main ()
{
clrscr();
string word;

while ( cin >> word )
cout << "Procitano slovo: " << word << "\n";
cout << "Vse slova procitany!";
return 0;
}
---------------------------------
По идее прога должна считывать предложение,введённое пользователем и выводить по одному слову. У м еня же она работает только если вместо string вставить char и то,выводит тогда по 1 букве!Я правильно понимаю,что в данной версии компилятора не поддерживается Standard Template Library ,в которую входит тип string?Если да,то начиная с какой он поддерживается?
Автор: SaDFromSpb
Дата сообщения: 26.11.2006 12:55
Arci21
С борландом 3.1 не знаком, но видимо у тебя стринг не из STL используется. Замени хедер <string.h> на <string> и в main'е string word; поменяй на std::string word;
Если не поможет, напиши как ругается (вообще то, это лучше сразу указывать).
А может он действительно STL не поддерживает...
Автор: rain87
Дата сообщения: 26.11.2006 13:20

Цитата:
Borland C++3.1
это досовский чтоли? конечно он не знает ни string, ни stl
там надо объявлять массив чаров и читать/писать скан/принтфом
Автор: blackdevil
Дата сообщения: 26.11.2006 23:12
Ребят, а у меня вот какая проблема...Прогу задали которая из градусов в радианы переводит и наоборот,причем сама определяет в чем я ввожу данные.Написал вот такой код:
#include <stdio.h>
int main ()
{
    char type;
    float arg;
    printf("You should enter value you want to convert (in degrees or radians). \n"
    "R means Radians,D means Degrees.Example: 1.5D or 34.87R \n \n"
    "Now please enter value: ");
    scanf ("%f%c",&arg,&type);
    if (type='R')
    {
    arg=arg*180/3.14;
    printf ("Your value is: %f degrees",arg);
    }
    if (type='D')
    {
    arg=arg*3.14/180;
    printf ("Your value is: %f radians",arg);
    }
    return 0;
}
Смысл в том что считываю с клавы числовое значение arg и символьное type и в зависимости от значения type выполняю пересчет. Все вроде компилируется но выполняется и первое условие if и второе.Я так понимаю проблема в самом условии.Как правильно написать ЕСЛИ type=БУКВЕ R ДЕЛАЙ ОДНО ЕСЛИ БУКВЕ D ТО ДРУГОЕ!?
Автор: xdude
Дата сообщения: 26.11.2006 23:28
Естественно будут выполняться оба! Ты ж не сравниваешь, а присваиваешь значение! Правильно будет так:

Код:
...
if (type=='R')
...
if (type=='D')
...
Автор: blackdevil
Дата сообщения: 27.11.2006 00:13
Ой,спасибо,чувак!!!Иногда чувствую себя таким ламмером...просто ужас )) Надеюсь когда-нить буду разбираться в этом так же как люди помогающие таким как я!
Автор: xdude
Дата сообщения: 27.11.2006 00:18
blackdevil
Все когда-то с чего-то начинают Успехов
Автор: Qraizer
Дата сообщения: 27.11.2006 15:16
Dayver2009
Нет, не в этом. Конструкторы char-потоков принимают аргументы в виде const char*, а ты даёшь ему AnsiString. Копилятор не смог преобразовать типы. Помоги ему сам. Например, std::string тоже не кастуется в C-строку, но у него есть метод std::string::c_str(), который это делает, поэтому нужно было бы записать что-то в этом роде
Код: std::string fileName;

std::cin >> fileName;

std::ifstream inFile(fileName.c_str());

Страницы: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193

Предыдущая тема: не знаю как назвать тему :-)


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.