Serjoga |
Отправлено: 25.11.2006, 15:24 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 9
|
Привет всем.
У меня такая проблема: Имеется массив int massiv[100]. Имеется файл Koord.txt в котором записаны числа. Нужно эти числа записать в массив. При попытке сделать это билдер ругается на несоответсвие типов в массиве и переменной куда записываются числа(FileRead(fname, &buff, 1)), тоесть в buff (int buff). Подскажите как это правильно сделать пожалуйста. |
|
BadMan |
Отправлено: 25.11.2006, 17:45 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 37
|
В лоб (если файл двоичный) так:
CODE |
//Объявление
int Massiv[100];
// Запись
FileWrite(Handle,Massiv,sizeof(Massiv));
// Чтение
FileRead(Handle,Massiv,sizeof(Massiv));
|
Но если файл текстовый — надо читать построчно, преобразовывать в число и записывать в массив
Отредактировано BadMan — 25.11.2006, 17:47 |
|
Serjoga |
Отправлено: 25.11.2006, 17:56 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 9
|
А если у меня в файле много цифр и нужно записывать в массив по 1? Например в massiv[0] первую цифру из файла? В файле несколько строк.
Например:
102030...
111213...
121314... |
|
BadMan |
Отправлено: 25.11.2006, 19:11 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 37
|
QUOTE (Serjoga @ 25.11.2006, 17:56) | ... В файле несколько строк...
|
Почему я и уточнял: файл текстовый или двоичный.
При работе с текстовым файлом такой вариант не пройдет — надо считывать построчно.
Если числа строго одинаковой длины и в каждой строке конкретное количество этих чисел, то можно использовать некое подобие хеширования и позиционировать указатель в файле исходя из номера нужного числа.
Если нет — то тут перебор строк, возможно некое индексирование и т.п.
Для того, чтобы определится со степенью наворотов нужно знать насколько большой файл предполагается обрабатывать — сколько в нем будет чисел. |
|
Serjoga |
Отправлено: 25.11.2006, 19:58 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 9
|
Немного обьясню что я хочу сделать.
Есть DrawGrid в нём нужно закрасить некоторые клетки в другой цвет. Координаты этих клеток хочу хранить в отдельном файле. Потом просто через цикл брать эти значения из файла помещать их в массив и закрашивать клетки...вот...Как взять целую строчку я знаю а как посимвольно без понятия |
|
BadMan |
Отправлено: 25.11.2006, 20:32 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 37
|
Тогда можно сделать что-то в этом роде:
CODE |
// Структура записывается в начало файла
Typedef struct
{
int ColCells;
// тут можно еще записать всяко разное — цвета и т.п.
} FileHeader;
// Струтура описывает координаты закрашиваемой ячейки
Typedef struct
{
int x_koord;
int y_koord;
} CellCoord;
SaveFile()
{
FileHeader HFile;
CellCoord Cell;
HFile.ColCells = // Количество записываемых ячеек
// Записали заголовок
FileWrite(Handle,&HFile,sizeof(HFile));
// Дальше идем по массиву нужных ячеек (не знаю как он у вас представлен)
for (i=0;i<размер массива;i++)
{
Cell.x_koord = // Столбец из массива
Cell.y_koord = // Строка из массива
// Записываем очередной элемент
FileWrite(Handle,&Cell,sizeof(Cell));
}
}
|
Чтение производим аналогично...
Если элементов много, то можно заменить int на word или short
|
|
Grigoriy |
Отправлено: 25.11.2006, 21:01 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
Вот функция по формированию массива байтов из файла с именем f с однобайтовыми числами.
Имя файла в этой функции задается нуль-терминальной строкой.
Если исходная строка типа AnsiString, то она преобразуется с помощью свойства c_str()
CODE |
int __stdcall ReadCharsNumbersFromFileToArray(char* f, void* m)
{
//f — имя файла с нуль-терминальной строкой
//m — указатель на массив байтов
//В случае неудачи функция возвращает -1
//В случае успеха функция возвращает 0
void* p;
void* r;
unsigned int k;
unsigned long k1;
if ((p=CreateFile(f,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0))==(void*)-1) return -1;
if (k=GetFileSize(p,0))
{
r=GlobalAlloc(0,k);
ReadFile(p,r,k,&k1,0);
asm{
pushad;
cld;
mov esi,r;
mov ecx,k;
mov edi,m;
@c1:
lodsb;
sub al,48;
jl @p1;
cmp al,9;
ja @p1;
stosb;
@p1:loop @c1;
popad;
};
GlobalFree(r);
};
CloseHandle(p);
return 0;
}; |
Отредактировано Grigoriy — 25.11.2006, 21:06
|
|
Shagg |
Отправлено: 25.11.2006, 21:31 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 69
|
а если так?
CODE | struct TCellColor
{
int x, y, color;
}
void load(char* file_name)
{
ifstream inf(file_name);
vector<TCellColor> vCells;
TCellColor ccl;
while (inf >> ccl.x >> ccl.y >> ccl.color) vCells.push_back(ccl);
inf.close();
} |
ЗЫ: вопрос Grigoriy'ю. Объясните пожалуйста, почему вы не используете потоки С++, а пользуетесь апишными функциями? Может я чего-то не знаю, просветите. |
|
Serjoga |
Отправлено: 25.11.2006, 22:04 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 9
|
Я начал программировать недавно поэтому немного не понимаю
У меня массив заполняется -1-цами(он типа integer). Потом эти значения переписываются, но чтобы не писать эту переписку прямо в коде хотел сделать чтение из файла...ну чтобы небыло чего-то подобного:
matrix2[0]=0;
matrix1[1]=2;
matrix2[1]=0;
matrix1[2]=3;
matrix2[2]=0;
matrix1[3]=4;
matrix2[3]=0;
Вот заполнение -1:
for (int i = 0; i < razmer; i++)
{
matrix1[i]=-1;
matrix2[i]=-1;
}
Потом заполняются ячейки:
for (int i=0; i < razmer; i++) {
if (matrix1[i]!=-1) {
tr=DrawGrid1->CellRect(matrix1[i],matrix2[i]);
DrawGrid1->Canvas->Brush->Color=clNavy;
DrawGrid1->Canvas->FillRect(tr);
}
}
Думую можно ограничится одним массивом, но это просто надо переделать код
Можно это както полегче и попонятней осуществить? |
|
Grigoriy |
Отправлено: 26.11.2006, 00:33 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
QUOTE | ЗЫ: вопрос Grigoriy'ю. Объясните пожалуйста, почему вы не используете потоки С++, а пользуетесь апишными функциями? Может я чего-то не знаю, просветите |
Решили "заесть" ?
Я использую АПИ потому, что так прикольнее и могу делать все что мне вздумается... в том числе и на асме.
Кроме того, я не пойму правильности кода и его работы пока не переведу его в уме на те же АПИ и работу компьютера.
То есть получается, для того, чтобы я смог написать всеми высшими средствами C++ Builder, мне сначала нужно представить
как программу должен выполнять компьютер, потом подобрать "рифмы" с возможностями высокоуровневых средств, чтобы обойтись без низкоуровневых. Так что так... Shagg.
|
|
Shagg |
Отправлено: 26.11.2006, 01:04 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 69
|
Grigoriy: не хотел я ни кого "заедать". Просто я далеко не профи в программировании и хотел узнать может действительно АПИ функции использовать предпочтительнее.
Serjoga:
изучайте STL. vector — это готовый класс массива. точнее шаблон класса
функция раскраски грида может выглядеть так:
CODE | void Paint(TDrawGrid *Grid, vector<TCellColor> vCells)
{
TRect rect;
for (vector<TCellColor>::iterator i=vCells.begin(); i != vCells.enf(); i++)
{
rect = Grid->CellRect(i->x, i->y);
Grid->Canvas->Brush->Color = i->color;
Grid->Canvas->FillRect(rect);
}
} | |
|
Grigoriy |
Отправлено: 26.11.2006, 01:49 |
|
Мастер участка
Группа: Участник
Сообщений: 381
|
QUOTE | может действительно АПИ функции использовать предпочтительнее. |
Так или иначе, компьютер все равно будет использовать АПИ.
А вот использовать ли АПИ в своем сознании — это решаете вы сами.
|
|
BadMan |
Отправлено: 26.11.2006, 12:18 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 37
|
Лично я не вижу никакого смысла в реализации тривиальной задачи чтения из файла в массив через ассемблер или API.
Гораздо проще, читабельнее и быстрее прочитать обычными функциями типа FileRead |
|
Serjoga |
Отправлено: 26.11.2006, 12:34 |
|
Ученик-кочегар
Группа: Участник
Сообщений: 9
|
Всем спасибо буду разбирпться. |
|