Часть 2. Я начинающий, подскажите как...(Все вопросы начинающих!!!)
ListBox1->Columns=3;
каким образом записать строку в второй и третий столбцы?
Одной функции, полагаю, нет
Подскажите - существуют ли в .NET удобные инструменты для чтения бинарных динамических данных? Помимо очевидного - ручного?
К примеру нужно считать простенькую последовательность:
[StructLayout(LayoutKind.Sequential)]
{
uint length; // длина каждой строки
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = length)]
string str1; // строка1
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = length)]
string str2; // строка1
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = length)]
string str3; // строка1
int someInt; // ...
}
Естественно, такая запись не работоспособна и SizeConst нужно указывать на этапе компиляции. Есть интеллектуальный способ это считать?
SerializableAttribute + BinaryFormatter - не?
Так это в том случае, если я сам записываю и считываю структуру. И в файл при этом будет записана доп. мета информация для дешифровки. А тут нужно считать чужую, полученную не сериалзиацией, а старой доброй ручной записью в поток. :) Старое доброе считывание из потока безусловно решает, но интересно - нет ли варианта попроще.
Тип того?
Ещё вот хорошая статья о генерации сериализатора/десериализатора в динамическую сборку. Можно тот код слегка перепилить - не для начинающих, но в принципе :)
В смысле? Я тогда не очень понимаю что же вам надо.
Исключить работу ручками. (=
Чтобы не было
var length = binaryReader.ReadInt();
vat string = Encoding.GetString(bynaryReader.ReadBytes(length));
А описание структуры с динамическими ссылками и одно короткое Read для ее прочтения. (=
Просто уже привык, что в .NET можно почти всё. Обленился. :D
#include <iostream>
#include <string>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::swap;
using std::vector;
//--------------------------------------------------------------
void QuickSort(vector<int>* sequence, int p, int r) {
int i = p;
int j = r;
int q = p + (r - p)/2;
do {
while (sequence->at(i) < sequence->at(q)) {
++i;
}
while (sequence->at(q) < sequence->at(j)) {
--j;
}
if (i <= j) {
int temp = sequence->at(i);
sequence->at(i) = sequence->at(j);
sequence->at(j) = temp;
++i;
--j;
}
} while (i <= j);
if (p < j) {
QuickSort(sequence, p, j);
}
if (i < r) {
QuickSort(sequence, i, r);
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void ChooseMinimumSort(vector<int>* sequence) {
for (int position = 0; position + 1 < sequence->size(); ++position) {
int minimum = sequence->at(position);
int index_of_minimum = position;
for (int i = position + 1; i < sequence->size(); ++i) {
if (sequence->at(i) < minimum) {
minimum = sequence->at(i);
index_of_minimum = i;
}
}
swap(sequence->at(position), sequence->at(index_of_minimum));
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void OutputSequence(const string& name,
const vector<int>& sequence) {
cout << name;
for (int i = 0; i < sequence.size(); ++i) {
cout << ' ' << sequence;
}
cout << endl;
}
//--------------------------------------------------------------
const int MAX_SEQUENCE_LENGTH = 4;
const int MAX_ELEMENT = 100;
//--------------------------------------------------------------
int main()
{
srand(239);
while(true)
{
int sequence_length = rand() % MAX_SEQUENCE_LENGTH + 1;
vector<int> sequence;
for (int i = 0; i < sequence_length; ++i) {
sequence.push_back(rand() % MAX_ELEMENT + 1);
}
vector<int> sequence_copy_for_bubble_sort = sequence;
QuickSort(&sequence_copy_for_bubble_sort,
0, sequence.size() - 1);
vector<int> sequence_copy_for_minimum_sort = sequence;
ChooseMinimumSort(&sequence_copy_for_minimum_sort);
if (sequence_copy_for_bubble_sort != sequence_copy_for_minimum_sort)
{
cout << "Wrong Answer!" << endl;
OutputSequence("Test:", sequence);
OutputSequence("Quick sort:", sequence_copy_for_bubble_sort);
OutputSequence("Minimum sort:", sequence_copy_for_minimum_sort);
break;
}
else
{
cout << "OK" << endl;
}
}
cin.ignore();
return 0;
}
OK
OK
OK
...
OK
OK
Wrong answer!
Test: 95 98 83 24
Quick sort: 24 95 83 98
Minimum sort: 24 83 95 98
void QuickSort(vector<int>* sequence, int p, int r) {
int i = p;
int j = r;
int q = sequence->at(p + (r - p)/2);
do {
while (sequence->at(i) < q) {
++i;
}
while (q < sequence->at(j)) {
--j;
}
if (i <= j) {
int temp = sequence->at(i);
sequence->at(i) = sequence->at(j);
sequence->at(j) = temp;
++i;
--j;
}
} while (i <= j);
if (p < j) {
QuickSort(sequence, p, j);
}
if (i < r) {
QuickSort(sequence, i, r);
}
}
//--------------------------------------------------------------
А то если опорный элемент поменяется дальше сортировка неправильно пойдёт.
Вопрос:
Пишу шаблонный класс Stack (на основе массива или вектора), в котором определяю метод
T& Stack<T>::take() const;
Метод take() возвращает ссылку на верхний (top) элемент стека, но не удаляет его (для этого служит метод void Stack<T>::pop());
Однако, когда стек пуст, что я должен возвращать?
Если я буду возвращать 0, то стек будет "узкопрофильным" - только для чисел или символов. А например для строк? Хотелось бы иметь полностью шаблонный, универсальный класс template <class T> class Stack{...};
Вот пример:
class Stack
{
private:
vector<T> data;
int next;
int size;
public:
Stack();
~Stack();
void push(T item);
void pop();
int getsize() const;
T& take() const;
bool empty() const;
};
//------------------------------------------------------
template <class T>
void Stack<T>::pop()
{
if (data.empty()) {
printf("\aStack is empty!\n");
} else {
data.pop_back();
--size;
--next;
}
}
//------------------------------------------------------
//------------------------------------------------------
template <class T>
T& Stack<T>::take() const
{
if (data.empty()) {
printf("\aStack is empty!\n");
// Здесь необходимо придумать, что возвращать в случае, если стек пуст. Иначе программа вылетает.
}
T item = data.back();
return item;
}
//------------------------------------------------------
Вопрос:
Пишу шаблонный класс Stack (на основе массива или вектора), в котором определяю метод
T& Stack<T>::take() const;
Метод take() возвращает ссылку на верхний (top) элемент стека, но не удаляет его (для этого служит метод void Stack<T>::pop());
Однако, когда стек пуст, что я должен возвращать?
Если я буду возвращать 0, то стек будет "узкопрофильным" - только для чисел или символов. А например для строк? Хотелось бы иметь полностью шаблонный, универсальный класс template <class T> class Stack{...};
На мой взгляд есть несколько вариантов:
- Возвращай указатель(когда стек пуст верни NULL). Хотя на сколько это правильно с контейнерами STL я уже не помню, т.к. не писал на C++ давно.
- Сделай метод isEmpty() и проверяй что стек не пуст перед тем, как читать из него(у тебя уже есть getsize(), который подойдёт для этого). А если всётаки прочитал из пустого стека - кидай эксепшн(и обрабатывай его выше по коду).
- Сделать метод bool tryTake(T* a), который вернёт элемент по указатель переданному в параметре, а через return - успешность\не успешность получения эл-та(на сколько это правильно в контексте работы с памятью в C++ опять же не могу сказать).
- Ну и хардкорный варинт - сделать собственный шаблонный класс обёртку над T. В котором можно как-либо указывать, что возвращённый объект - пустышка(думаю в данном случае это будет худший вариант).
Я бы выбрал 2й вариант, а в ветке ошибки кидал бы эксепшн.
Возникла следующая проблема при чтении строк из файла ..
файл имеет вид:
*длинное слово*
*короткое*
так вот, после считывания второй строки, выделенный под это дело символьный массив имеет вид:
*короткое*0ово
почему хвост с чтения предыдущей строки остается?
в задаче требуется считывать строчки и кидать их в динамический массив класса vector
вот как всё реализовано
vector<string> data;
char buf[41];
fstream fl("input.txt");
if (!fl)
{
cout<<"Error";
exit(1);
}
while(fl)
{
fl.getline(buf,40);
data.push_back(buf);
}
#include <string>
#include <fstream>
int main( ) {
std ::vector <std ::string>
data;
char buff[ 41 ];
std ::fstream fl;
fl .open( "input.txt" );
if( 0 == fl )
return 1;
while( fl ) {
fl .getline( buff, 40 );
data .push_back( buff );
}
fl .close( );
return 0;
}
#include <string>
#include <fstream>
int main( ) {
std ::vector <std ::string>
data;
char buff[ 41 ];
std ::fstream fl;
fl .open( "input.txt" );
if( 0 == fl )
return 1;
while( fl ) {
fl .getline( buff, 40 );
data .push_back( buff );
}
fl .close( );
return 0;
}
почему-то считываются только первые 5 строк, дальше он выходит
оказывается в текстовом файле размер строки был превышен)
cout<<data[numMin]<<endl; //выдаёт ошибку =(
Какую ошибку? И код лучше целиком приводить.
#include <string>
#include <fstream>
#include <iostream>
int main( ) {
std ::vector <std ::string>
data;
char buff[ 41 ];
std ::fstream fl;
int n;
fl .open( "input.txt" );
if( 0 == fl )
return 1;
while( fl ) {
fl .getline( buff, 40 );
data .push_back( buff );
}
fl .close( );
n = data .size( );
while( n-- )
std ::cout << data[ n ] << std ::endl;
return 0;
}
тегами code пользуйтесь
Какую ошибку? И код лучше целиком приводить.
#include <string>
#include <fstream>
#include <iostream>
int main( ) {
std ::vector <std ::string>
data;
char buff[ 41 ];
std ::fstream fl;
int n;
fl .open( "input.txt" );
if( 0 == fl )
return 1;
while( fl ) {
fl .getline( buff, 40 );
data .push_back( buff );
}
fl .close( );
n = data .size( );
while( n-- )
std ::cout << data[ n ] << std ::endl;
return 0;
}
тегами code пользуйтесь
#include <fstream>
#include <windows.h>
#include <cstdio>
#include <vector>
using namespace std;
vector<string> data;
int main()
{
char buf[51];
setlocale(LC_CTYPE, "Russian");
cout<<"short:"<<endl;
fstream fl("lolita.txt");
if( 0 == fl )
return 1;
while( fl ) {
fl .getline( buf, 40 );
data .push_back( buf );
}
fl .close( );
int numMin=0;
int min=data[0].size();
for (int i=1;i<data.size();i++)
{
if (data.size()<min) {numMin=i; min=data.size();}
}
fl.close();
cout << data[ numMin ]<<endl; //здесь ошибку выдаёт
return 0;
}
по условию надо вывести минимальную из всех встретившихся строчек
#include <string>
#include <fstream>
#include <iostream>
int main( ) {
std ::vector <std ::string>
data;
char buff[ 41 ];
std ::fstream fl;
int n,
min,
numMin;
fl .open( "input.txt" );
if( 0 == fl )
return 1;
while( 0 == fl .eof( ) ) {
fl .getline( buff, 40 );
data .push_back( buff );
}
fl .close( );
n = data .size( );
while( n-- )
std ::cout << data[ n ] << std ::endl;
n = data .size( ) - 1;
numMin = n;
min = data[ n ] .size( );
while( n-- )
if( data[ n ] .size() < min ) {
numMin = n;
min = data[ n ] .size( );
}
std ::cout << data[ numMin ] << std ::endl; //здесь ошибку выдаёт
return 0;
}
ЗЫ. проверку конца файла производите неверно.
#include <string>
#include <fstream>
#include <iostream>
int main( ) {
std ::vector <std ::string>
data;
char buff[ 41 ];
std ::fstream fl;
int n,
min,
numMin;
fl .open( "input.txt" );
if( 0 == fl )
return 1;
while( 0 == fl .eof( ) ) {
fl .getline( buff, 40 );
data .push_back( buff );
}
fl .close( );
n = data .size( );
while( n-- )
std ::cout << data[ n ] << std ::endl;
n = data .size( ) - 1;
numMin = n;
min = data[ n ] .size( );
while( n-- )
if( data[ n ] .size() < min ) {
numMin = n;
min = data[ n ] .size( );
}
std ::cout << data[ numMin ] << std ::endl; //здесь ошибку выдаёт
return 0;
}
ЗЫ. проверку конца файла производите неверно.
спасибо =)
p.s. учат хреново, значит)
сейчас всех хреново учат, и ИМХО в этом суть перехода к западной системе образования. В США ведь нет лекций в той форме что у нас, у них студент готовится к лекции, и там препод не рассказывает все все все, а лишь беседует по теме. Ну и раз к нам приглашают профессоров из США и Европы - то держат курс на их систему(ну и бакалавры с магистрами тому подтверждение). Мой вывод: систему высшего образования пытаются превратить в СИСТЕМУ самообразования(это отличается от просто самообразования). А значит, теперь нельзя винить препода, все дело в желании студента получать знания.
ЗЫ. извиняюсь за оффтоп.
сейчас всех хреново учат, и ИМХО в этом суть перехода к западной системе образования. В США ведь нет лекций в той форме что у нас, у них студент готовится к лекции, и там препод не рассказывает все все все, а лишь беседует по теме. Ну и раз к нам приглашают профессоров из США и Европы - то держат курс на их систему(ну и бакалавры с магистрами тому подтверждение). Мой вывод: систему высшего образования пытаются превратить в СИСТЕМУ самообразования(это отличается от просто самообразования). А значит, теперь нельзя винить препода, все дело в желании студента получать знания.
ЗЫ. извиняюсь за оффтоп.
да, пожалуй, слегка погорячился, обвинив только тех, кто преподаёт. здесь львиная доля вины самих обучающихся, НО, на некоторых вещах преподаватели настаивают и проще согласиться с ними, чем рыться в источниках и разбираться самому. Конечно, результат ещё зависит от заинтересованности студента (тогда количество хренового кода сводится к минимуму) в предмете и времени.
Подскажите какая разница использовать для преобразования конструктор с параметром или перегрузить "="?
ClassTwo::ClassTwo(ClassOne ObjName){...}
Оба варианта работают.
Полные коды прикрепил.
[ATTACH]5351[/ATTACH]
[ATTACH]5350[/ATTACH]
Подскажите какая разница использовать для преобразования конструктор с параметром или перегрузить "="?
Вопрос не такой простой как кажется, а разница довольно существенная. Могу предложить для начала почитать про явные (explicit) конструкторы.
Подскажите какая разница использовать для преобразования конструктор с параметром или перегрузить "="?
ClassTwo::ClassTwo(ClassOne ObjName){...}
Оба варианта работают.
Полные коды прикрепил.
[ATTACH]5351[/ATTACH]
[ATTACH]5350[/ATTACH]
Если логика поведения класса предполагает создание одной сущности на основе другой сущности - тогда используйте конструктор.
Примером в реальном мире может служить на основе сущности СЕМЕНА создается РАСТЕНИЯ.
Если необходимо выполнять приведение от одной сущности к другой сущности - тогда перегрузку. Примером может служить ЯБЛОКИ являются ФРУКТАМИ.
Понятно что это весьма упрощенный пример.
Появилась задача, написать программу, попросил знакомого, он начал писать на C# и забросил, я продолжаю.
Сложность программы простейшая:
1). Существует форма, на которой находятся 4 кнопки, на две из которых нужно сделать подтверждение на выполнение той или иной функции. Как это сделать я так и не понял, хотя вроде перебрал не мало примеров. Я конечно больше склоняюсь к своей криворукости, так как работаю в C# недельку от силы.
2). Как сделать так, что бы radio был активен, только тогда, когда скрол с текстом был опущен до самого конца (что популярно в задачах, где используется лицензионное соглашение).
Вот программа [COLOR="red"][ссылка удалена][/COLOR]
2. "Скрол с текстом" - это что? Какой компонент используется?
В следующий раз за размещение ссылок на файлообменники выдам бан как за спам.
это вообще не понял, сформулируйте нормально
struct comp
{
char Name[20],
Author[20];
int year;
comp *next;
};
struct DynamicList
{
comp *head,
*tail;
};
class Library
{
DynamicList l;
public:
Library()
{
l .head = 0;
}
void Add()
{
char Nam[20];
char Aut[20];
int yea;
std ::cout << "Input the name of book: ";
std ::cin >> Nam;
std::cout << "Input the name of Author: ";
std::cin >> Aut;
std::cout << "Input the year: ";
std::cin >> yea;
comp *c = new comp( );
strcpy_s( c ->Name, 20, Nam );
strcpy_s( c ->Author, 10, Aut );
c->year=yea;
c ->next = NULL;
if( 0 == l.head )
l .head = l .tail = c;
else
l .tail = l .tail ->next = c;
}
void Show ( )
{
comp *p = l .head;
while ( p ) {
std ::cout << p ->Name << " " << p ->Author << " " << p->year << std ::endl;
p = p ->next;
}
}
void Search()
{
char search[20];
std::cout << "Input the name of Author: \n";
std::cin >> search;
int vybor=0;
comp *p =l.head;
vybor = 0;
for(;;)
{
std::cout << "1-By Author\n2-By NameofBook" << std::endl;
std ::cin >> vybor;
switch( vybor )
{
case 0:
std::cout << "Input the name of Author: \n";
std::cin >> search;
while (p)
{
if (!strcmp(p->Author,search))
std::cout << p->Name << " " << p->Author << std::endl;
p=p->next;
}
break;
case 1:
std::cout << "Input the name Name of book: \n";
std::cin >> search;
while (p)
{
if (!strcmp(p->Name,search))
std::cout << p->Name << " " << p->Author << std::endl;
p=p->next;
}
break;
}
}
}
void Sort()
{
comp *p=l.head;
char temp1[20];
char temp2[20];
while (p->next)
{
if (strcmp(p->Author,(p->next)->Author)>0)
{
strcpy(temp1,p->Author);
strcpy(p->Author,(p->next)->Author);
strcpy((p->next)->Author,temp1);
strcpy(temp2,p->Name);
strcpy(p->Name,(p->next)->Name);
strcpy((p->next)->Name,temp2);
}
p=p->next;
}
}
};
int main( ) {
Library lol;
int vybor;
vybor = 0;
for(;;)
{
std::cout << "1-ADD\n2-Show\n3-Search" << std::endl;
std::cout << "4-Sort\n0-Exit" << std::endl;
std ::cin >> vybor;
switch( vybor )
{
case 0:
return 0;
case 1:
lol .Add();
break;
case 2:
lol .Show( );
break;
case 3:
lol.Search();
break;
case 4:
lol.Sort();
break;
default:
std ::cout << "";
}
}
}
Я так понимаю, что код вы откуда-то скопипастили. Вам уже ответили тут
я бы вам посоветовал изменить цикл(который у вас уже есть так, чтобы в нем искался минимум хвоста списка. Тогда внешний цикл(который надо добавить) должен меня местами голову списка и минимум хвоста). И вам полюбому потребуется еще один указатель, т.к. список у вас однонаправленный.
int b = 0;
int c = 0;
__asm{
mov eax, a
mov ebx, b
add eax, ebx
...
}
как то так...
__asm{
mov eax,a
add eax,b
…
}
Имеем: простенькая программка, которая написана на C#.
Программа написана на Visual Studio 2008 SP1 (ОС - Windows 7). Приложение, которое разрабатывается, будет работать на Windows XP SP2. Повышение версии ОС возможно, но нежелательно.
На Windows XP поставил .NET Framework 3.5 SP1 (который сразу с Client Profile). Но при запуске приложения постоянно появляется ошибка:
To download this required update go to http://microsoft.com/downloads
В общем, вроде все очевидно. НО. Target Framework для приложение - 2.0. Пробовал ставить целевой фреймворк и 3.0, и 3.5 (+галочка для Client Profile) - результат один и тот же.
Вопрос - каким образом можно заставить это приложение работать на SP2?
P.S. Само приложение - стандартная формочка на Windows Forms с обработчиками событий + периодически шлётся HttpWebRequest.
==== Update
Обновился до Windows XP SP3 + поставил dotNet 4.0 Client Profile - ошибка та же самая