С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++/CLI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/32: Рейтинг темы: голосов - 32, средняя оценка - 4.78
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477

Обращение к элементам динамического двумерного массива

15.03.2013, 12:54. Показов 5988. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть файл, записанный с помощью _write значениями типа float, пытаюсь забирать данные через _read, если массив создан через
C++
1
float coord[32][2]
то _read читает всё верно. Но если я пытаюсь объявить его динамически:
C++
1
2
3
4
5
6
7
8
9
FILE *fp=fopen("test.par","r");
int size = filelength(fileno(fp));//Размер файла. 
const int xy=size/(2*sizeof(float));
float** coordc;
coordc = new float*[xy];
for (int i=0; i<xy; i++)
{
    coordc[i]=new float[2];
}
то при попытке забрать значения путем:
C++
1
2
3
4
5
                 char cc[128];
                 strcpy_s(cc, "test.par");
                 static int fh = 0;
                 int hf = _sopen_s(&fh,cc,_O_RDONLY,_SH_DENYNO,_S_IREAD);
                 _read(fh,*coordc,sizeof(coordc));
не понимаю - как значения получить, простым обращением по coordc[i][j] не получается, бред выводит
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.03.2013, 12:54
Ответы с готовыми решениями:

обращение к элементам на разных формах и видимость
помогите новичку на форме есть кнопка и textBox1 . две проблемы. 1.как обратиться к textBox1 не из Form1.h (как в builder...

Создание динамического двумерного массива Button-ов
Столкнулся со следующей проблемой: необходимо создать динамический двумерный массив типа Button. В вижуале массивы такого типа создаются...

Заполнение двумерного динамического массива из DataGridView
Ребят, такая проблема: есть DataGridView, в него без проблем заполняются целые числа из двумерного массива (предварительно рандомно...

11
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
15.03.2013, 13:03
sizeof(coordc) ошибка
получаете SIZEOF c указателя - получите размер указателя
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
15.03.2013, 13:15  [ТС]
C++
1
2
3
4
5
6
7
FILE *fp=fopen("test.par","r");
int size = filelength(fileno(fp));//Размер файла. 
char cc[128];
strcpy_s(cc, "test.par");
static int fh = 0;
int hf = _sopen_s(&fh,cc,_O_RDONLY,_SH_DENYNO,_S_IREAD);
_read(fh,*coordc,size);
Так верно?
тогда при обращении к coordc[0][0] -верно, [0][1] - верное, [1][0] - не верно, [0][2] - тут то, что должно быть в [1][0]. Я неправильно объявляю?

Добавлено через 2 минуточки
еще при _read теперь
"Необработанное исключение типа "System.AccessViolationException" произошло в msvcm90d.dll
Дополнительные сведения: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена."
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
15.03.2013, 23:06
Выдалась свободная минутка , потестил и вправду исключение вываливается
Правда со статическим массивом все в норме
Проверял так , используя fstream ,(что там у вас за функции не знаю а разбираться не было возможности)
C++
1
2
3
outfile.write((char*)&coordc, sizeof(coordc) /sizeof(float) );
////////////////////////////////////////////////////////////////
infile.write((char*)&coordc, sizeof(coordc) /sizeof(float) );
Но с динамическим можно поэлементно сохранить в файл
рабочий пример
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
 
 
int main()
{
    srand(time(NULL));
    const int ROW = 10;
    const int COL = 2;
 
    float** coordc;
    coordc = new float*[ROW];
    for ( int i = 0; i < ROW; i++)
    {
        coordc[i] = new float[COL];
    }
 
 
     float** NEWcoordc;
    NEWcoordc = new float*[ROW];
    for ( int i = 0; i < ROW; i++)
    {
        NEWcoordc[i] = new float[COL];
    }
 
 
    std::cout << "Old Array" << std::endl ;
    for (int i = 0; i < ROW; i++)
    {
        std::cout << std::endl ;
        for (int j = 0; j < COL; j++)
        {
            coordc[i][j] =  0.1 * float(rand() % 100);
            std::cout << coordc[i][j] << "      ";
        }
    }
 
    std::cout << std::endl ;
 
    ///  WRITEFILE 
    ////////////////////////////////////////////
    std::ofstream outfile("F:\\BinFile.bin",std::ios::out | std::ios::binary);
  
    for (int i = 0; i < ROW; i++)
        for (int j = 0; j < COL; j++)
    outfile.write((char*)&coordc[i][j], sizeof(float) );
    outfile.close();
 
    ///  READFILE 
    ////////////////////////////////////////////
    std::ifstream infile("F:\\BinFile.bin",std::ios::in | std::ios::binary);
  for (int i = 0; i < ROW; i++)
        for (int j = 0; j < COL; j++)
     infile.read((char*)&NEWcoordc[i][j], sizeof(float)  );
    infile.close();
 
    //////////////////////////////////////////////////
 
    std::cout << std::endl  << "New Array" << std::endl ;
 
    for (int i = 0; i < ROW; i++)
    {
        std::cout << std::endl ;
        for (int j = 0; j < COL; j++)
        {
            std::cout << NEWcoordc[i][j] << "      ";
        }
    }
 
    for(int i = 0; i < ROW; i++)
    delete [] coordc[i];
delete [] coordc;
 
 
 
    for(int i = 0; i < ROW; i++)
    delete [] NEWcoordc[i];
delete [] NEWcoordc;
 
}
А вообще не пойму, почему под координаты не используете структуру ?
так легче и в файл записать
Здесь что -то подобное писал
Сортировка структуры
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
16.03.2013, 11:22  [ТС]
C++
1
2
3
4
5
struct coord {
    int id;
    float x;
    float y;
};
Предположим так, а потом что?
мне же нужен двумерный массив неизвестной длины
в данном случае одномерный массив структур?

Добавлено через 6 минут
ну, правда, если я буду создавать массив структур неопределенного размера, то мне можно так:
C++
1
2
3
4
struct coord {
    float x;
    float y;
};
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
16.03.2013, 15:52
Цитата Сообщение от KokosSPb Посмотреть сообщение
создавать массив структур неопределенного размера
Вообщето вектор есть для этого

KokosSPb, можно ведь размер массива в файл записать,
а по нему
уже создавать новый массив
.Структуру POINT взял для удобства из Windows.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <Windows.h>
 
std::ostream & operator << (std::ostream & os, const POINT & point)
{
    os << " X = " << point.x  << "  Y = " << point.y;
    return os;
}
 
int main()
{
    srand(time(NULL));
    const int ROW = 10;
 
    POINT *coordc    = new POINT[ROW];  
    POINT *NEWcoordc = NULL;
 
    std::cout << "Old Array" << std::endl ;
    for (int i = 0; i < ROW; i++)
    {   
            coordc[i].x  =  rand() % 100;
            coordc[i].y  =  rand() % 100;
            std::cout << coordc[i] << std::endl;
    }
 
    std::cout << std::endl ;
 
    ///  WRITEFILE 
    ////////////////////////////////////////////
    std::ofstream outfile("F:\\BinFile.bin", std::ios::binary);
 
    // CНАЧАЛА ЗАПИСЫВАЕМ КОЛИЧЕСТВО СТРУКТУР 
    outfile.write((char*)&ROW, sizeof(int));
 
    for (int i = 0; i < ROW; i++)
    outfile.write((char*)&coordc[i], sizeof(POINT));
    outfile.close();
 
    std::cout << std::endl  << "New Array" << std::endl ;
    ///  READFILE 
    ////////////////////////////////////////////
    std::ifstream infile("F:\\BinFile.bin", std::ios::binary);
 
    int PointsSize = 0; //КОЛИЧЕСТВО СТРУКТУР 
 
    // СЧИТЫВАЕМ КОЛИЧЕСТВО СТРУКТУР 
    infile.read((char*)&PointsSize, sizeof(int) );
 
    // СОЗДАЕМ НОВЫЙ МАССИВ ПО РАЗМЕРУ
    NEWcoordc  = new POINT[PointsSize];
 
    // ЗАПОЛНЯЕМ ИЗ ФАЙЛА 
    for (int i = 0; i < PointsSize; i++)
    {
        infile.read((char*)&NEWcoordc[i], sizeof(POINT) );
        std::cout << NEWcoordc[i] << std::endl ;
    }   
    
     infile.close();
 
    //////////////////////////////////////////////////
 
    delete  []coordc;
    delete  []NEWcoordc;
 
    std::cin.get();
}

Не охота размер в файл писать - значит через массив указателей
Правда считает на 1 структуру больше
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    POINT *NEWcoordc[200] ;
 
    int counter = 0; // КОЛИЧЕСТВО СТРУКТУР
    std::ifstream infile("F:\\BinFile.bin", std::ios::binary);
    
    // ЗАПОЛНЯЕМ ИЗ ФАЙЛА 
    while(! infile.eof())
    {
        NEWcoordc[counter]  = new POINT();
        infile.read((char*)NEWcoordc[counter], sizeof(POINT) );       
        counter++;
    }   
    
     infile.close();
 
    //////////////////////////////////////////////////
 
     // ВЫВОДИМ НА ОДНУ МЕНЬШЕ 
     for (int i = 0; i < counter - 1; i++)
     {
        std::cout << *NEWcoordc[i]<< std::endl ;
     }
 
     //  УДАЛЯЕМ 
      for (int i = 0; i < counter; i++)
     {
        delete NEWcoordc[i];
     }
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
18.03.2013, 09:57  [ТС]
Цитата Сообщение от MrCold Посмотреть сообщение
KokosSPb, можно ведь размер массива в файл записать,
а по нему
да я просто не знаю размер массива какой получится, он просто пишется в файл, пока пишется, а потом заканчивает писаться, я в этот момент конечно его знаю, но по факту я записываю много маленьких массивов подряд. Из конца файла я не могу его вытащить, только если читать весь файл, очищать содержимое, записывать размер массива, а потом заливать содержимое обратно. Но зачем? я же могу взять его массу, поделить на массу элемента(они все одинаковые) и выяснить их количество

Добавлено через 16 минуток
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
                 FILE *fp=fopen("test.par","r");
                 unsigned int size = filelength(fileno(fp));
                 int xy=size/(2*sizeof(float));
                 float** coordc;
                 float* coordf = new float[xy*2];
                 coordc = new float*[xy];
                 for (int i=0; i<xy; i++)
                 {
                     coordc[i]=new float[2];
                 }
                 char cc[128];
                 strcpy_s(cc, "test.par");
                 static int fh = 0;
                 int hf = _sopen_s(&fh,cc,_O_RDONLY,_SH_DENYNO,_S_IREAD);
                 _read(fh,coordf,size);
                 _close(fh);
                 for(int ii=0;ii<xy;ii++){
                     coordc[ii][0]=coordf[2*ii];
                     coordc[ii][1]=coordf[2*ii+1];
                 }
                 delete  []coordf;
сделал так
0
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
21.03.2013, 13:03  [ТС]
Народ, проблема:
Он записывает, вроде, всё верно, но при записи Синусоиды
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
                 char cc[128],name[25];//Объявляем переменные имени и названия баз
                 float coord[64][2];
                 String^ nameT;// Объявляем строковую переменную имени
                 nameT = "2_.Test"+"_.par";//Называем переменную имени файла
                 int ic;//Переменная номера символа
                 for(ic=0;ic<nameT->Length;ic++){
                     cc[ic]=nameT[ic];//Применение названия файла в массив
                 }
                 cc[ic] = 0;//Конец ввода
 
                 static int fh = 0;//Объявляем дескритор файла
                 int hf = _sopen_s(&fh,cc,_O_CREAT|_O_RDWR|_O_APPEND,_SH_DENYNO,_S_IREAD|_S_IWRITE);//Открываем файл и записываем егов  дискриптор
                 for(int iw=0;iw<10;iw++)
                 {
                    static float ds=0;
                    for(int ii=0;ii<64;ii++){
                        coord[ii][0]=50+25*sin(ds);
                        coord[ii][1]=50+25*cos(ds);
                        ds+=0.1;
                    }
                    _write(fh,coord,sizeof(coord));//Записываем значение в файл
                 }
                 _close(fh);//Закрываем файл
он при дебаге - записывает, вроде всё верно, а вот при считывании:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
                 char cc[256];
                 String^ nameT;
                 DateTime^ date;
                 date=DateTime::Now;
                 nameT="2_.Test_.par";
                 int ic;
                 for(ic=0;ic<nameT->Length;ic++){
                     cc[ic]=nameT[ic];
                 }
                 cc[ic] = 0;
                 FILE *fp=fopen(cc,"r");
                 unsigned int size = filelength(fileno(fp));//Размер файла. 
                 char name[25];
                 int xy=size/(2*sizeof(float));
                 float** coordc;
                 float* coordf = new float[xy*2];
                 coordc = new float*[xy];
                 for (int i=0; i<xy; i++)
                 {
                     coordc[i]=new float[2];
                 }
                 static int fh = 0;
                 int hf = _sopen_s(&fh,cc,_O_RDONLY,_SH_DENYNO,_S_IREAD);
                 listBox1->Items->Clear();
                 array<String^>^ namelist = gcnew array<String^>(xy);
                 String^ nameS;
                 _read(fh,coordf,size);
                 for(int ii=0;ii<xy;ii++){
                     coordc[ii][0]=coordf[2*ii];
                     coordc[ii][1]=coordf[2*ii+1];
                 }
                 _close(fh);
значения 0-37 верные, а далее непонятная хрень
И размер файла получается не 5120 байт, а 5143 байт
0
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
22.03.2013, 13:23  [ТС]
нет, не понимаю, если записываю 100 и более char[25], то всё верно записывается и размер файла ровный, как положено, если записываю пустые float[64][2] - тоже всё норм, если я их заполняю белибердой, типа 0.0001, всё гуд, но если я впихиваю в них дискретные значения синусоиды, то всё, сразу байда с размерами, записью и, соответсвенно, чтением
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
22.03.2013, 14:50
Не пойму почему не использовать Лист точек (List<PointF>) ?

Предложу альтернативу раз уж CLI используете

C++
1
2
3
    using namespace System::IO;
    using namespace System::Runtime::Serialization;
    using namespace System::Runtime::Serialization::Formatters::Binary;
заносим координаты в лист и сериализуем в файл
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
        float coord[64][2];
 
        // список Точек в который запишем координаты 
        System::Collections::Generic::List<System::Drawing::PointF>^ pointList = gcnew  System::Collections::Generic::List<System::Drawing::PointF>();
                 for(int iw = 0;iw < 10; iw++)
                 {
                    static float ds = 0;
                    for(int ii = 0;ii < 64; ii++){
                        coord[ii][0]= 50 + 25 * Math::Sin(ds);
                        coord[ii][1]= 50 + 25  * Math::Cos(ds);
 
                        // заносим координаты в Лист 
                        pointList->Add( System::Drawing::PointF(coord[ii][0], coord[ii][1]));
 
                        // выводим координаты для проверки в первый РичтекстБокс 
                        richTextBox1->AppendText(String::Format("X = {0}  Y = {1}\r\n", coord[ii][0], coord[ii][1]));
 
                        ds+=0.1;
                    }
                 }
 
                 //  Сериализуем наш лист в Файл 
            Stream^ stream = File::Open("ListOfPoints.dat", FileMode::OpenOrCreate);
            BinaryFormatter^ bformatter = gcnew BinaryFormatter();
 
                bformatter->Serialize(stream, pointList);
                stream->Close();
обратный процесс - чтение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
             // Создаем новый лист из  файла 
 
Stream^  stream = File::Open("ListOfPoints.dat", FileMode::Open);
BinaryFormatter^ bformatter = gcnew BinaryFormatter();
 
System::Collections::Generic::List<System::Drawing::PointF>^ newPointsList = (System::Collections::Generic::List<System::Drawing::PointF>^)bformatter->Deserialize(stream);
stream->Close();
 
 
//  выводим координаты для проверки во второй  РичтекстБокс 
for each (PointF point in newPointsList)
{
     richTextBox2->AppendText(String::Format("X = {0}  Y = {1}\r\n", point.X, point.Y));
    
}
Миниатюры
Обращение к элементам динамического двумерного массива  
1
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
22.03.2013, 21:59  [ТС]
Цитата Сообщение от MrCold Посмотреть сообщение
Не пойму почему не использовать Лист точек (List<PointF>) ?
На самом деле всё очень просто, просто мне нужно координаты не одной случайной ломаной линии, а четырех, а может и 16 понадобится. По этой причине, я просто тестил на 64х2, а по факту, это либо 64х2х4 либо 64х8, что уж поделать, там разобраться проще будет мне не понятна следующая дурь, 64*float = 512 байт, почему файл весит 513 байт? А записывать надо все в один файл, чтоб информацию пакетом забирать... вот
0
128 / 86 / 10
Регистрация: 03.02.2011
Сообщений: 477
03.04.2013, 10:02  [ТС]
Для тех, кому интересно, как это решить
Добавьте _O_BINARY
C++
1
int hf = _sopen_s(&fh,cc,_O_CREAT|_O_RDWR|_O_APPEND|_O_BINARY,_SH_DENYNO,_S_IREAD|_S_IWRITE);

Для тех, кому интересно, почему такое происходит
Так получилось, что синус стал равен, к примеру, 0.85459959507, т.е. в hex он будет выглядеть так: 0x0AC75A3F, ну а если по отдельности: 0x0A 0xC7 0x5A 0x3F. 0x0A в ASCII это символ перехода на следующую строку. Так вот при записи данных в текстовом режиме 0x0A будет заменяться на 0xD00A. Т.е. получаем 1 лишний байт.

За ответ спасибо anmartex, ссылка для спасибок
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
03.04.2013, 10:02
Помогаю со студенческими работами здесь

Обращение к элементам формы
Хочу из cpp сменить свойство (Text) элемента textBox1. При Form1-&gt;textBox1-&gt;Text = &quot;Test&quot;; выдает ошибку, что нету &quot;;&quot; перед...

Обращение к элементам формы из .cpp
Как обратиться к элементам формы из .cpp. Добавлено через 17 часов 3 минуты Неужели нельзя ? и все пишут в этот огромный header ?

Обращение из одного обработчика событий к элементам, объявленным в другом обработчике
Нужно по нажатию кнопки button1 удалить двумерный массив кнопок, созданный в Form1_Load. Не знаю, как обратиться к элементам массива. ...

Косвенное обращение к элементам динамического массива
Доброго времени суток. Необходима помощь с программой. Текст задачи: Заданы два массива А(5) и В(4). Первым на печать вывести массив,...

Обращение к элементам двухмерного динамического массива
Строки в двумерном динамическом массиве расположены не вплотную друг к другу. Тогда почему чтобы получить значение из массива оператор ar...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru