• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Как считать двумерный массив чисел из файла?

  • Автор темы Di_Ex
  • Дата начала
Статус
Закрыто для дальнейших ответов.
D

Di_Ex

Добрый день! Необходимо считать двумерный массив чисел из файла (квадратную матрицу размера n*n), причём размер массива заранее неизвестен. Числа разделены пробелами, например:

1 12 4 5
3 6 7 9
2 0 3 6
13 15 27 4

Собственно говоря, всё это мне нужно для того, что-бы решить СЛАУ методом ГАУСА ;) Так что если у кого-то есть информация по теме либо исходники - you are welcom :rolleyes:
Буду рад вашей помощи! Заранее благодарен.
 
M

mms

Так надо считать массив или что-то решить? :rolleyes:
 
S

shisik

Что-то мне не нравиться такой подход. Но очевидно это стоит в условии задачи :( Вы хотите читать из текстового файла строки, где числа разделены пробелами. Тогда нужно написать функцию поиска этих пробелов и таким образом выделить строки, содержащие эти числа. Затем их надо будет перевести в числовой тип (скажем, int или float, в зависимости от задачи). Строки матрицы у вас в файле, я так понимаю, отделены символами новой строки ("\r\n"). Значит одна строка будет содержать n-1 пробелов. Тогда для определения n нужно посчитать количество пробелов до первого \r\n и добавить 1. Затем массив будет создан как
Код:
int **matrica;
matrica = new int *[n];
for (int i =0; i < n; i++)
matrica[i] = new int[n];
Очищать память следует в обратном порядке:
Код:
for (i = 0; i < n; i++)
delete matrica[i];
delete matrica;
Я попробую что-то подобное сделать :) Хотя я считаю, что лучше в файл писать не строки а сразу массив типа int или float. А n вычислять не через количество пробелов, а как квадратный корень из длинны файла, делённой на sizeof(тип).
 
D

Di_Ex

Жду с нетерпением. Только на C, а не на C++ )
 
S

shisik

На C, так на C :( Программу проверял в VC++ 6.0
Код:
#include "stdafx.h"
#include "windows.h" //для фукций работы с файлами и проекциями файлов
#include "shlwapi.h" //для StrToInt()
#include "malloc.h" //для динамического выделения памяти

#define FILENAME "file.txt" //имя файла

int main(int argc, char* argv[])
{
HANDLE hFile = CreateFile(FILENAME, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL); //открываем файл
if (hFile == INVALID_HANDLE_VALUE) //если файла нет
return 1; //то выходим с кодом 1
HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); //проецируем файл в память
char *fmatr = (char *) MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); //получаем указатель на начало проекции

int **matrica;
unsigned i, n = 1;
for (i = 0; i < strlen(fmatr); i++) { //определяем 
if (fmatr[i] == ' ')			 //число
n++;				  //пробелов
if (fmatr[i] == '\r')		  //в первой строке
break;
}
matrica = (int **) calloc(n, sizeof(int*)); //выделяем память под массив указателей
for (i = 0; i < n; i++) //содержащий
matrica[i] = (int *) calloc(n, sizeof(int)); //массивы чисел

int j = 0, a = 0, n1 = 0, n2 = 0;
char val[3] = "";
for (i = 0; i < strlen(fmatr); i++) { //читаем проекцию файла (работаем как со строкой)
if (fmatr[i] == '\r') { //при завершении строки
matrica[n1++][n2] = StrToInt(val); //пишем значение и переходим на новую
n2 = 0;
i++;
j++;
a = 0;
strcpy(val, "");
continue; 
}
if (fmatr[i] != ' ') //если не пробел
val[a++] = fmatr[i];//то добавляем символ к строке, седержащей элемент матрицы 
else {//а если пробел
matrica[n1][n2++] = StrToInt(val); //то пишем значение и переходим к новой ячейке
a = 0;
strcpy(val, "");
}
}
matrica[n1][n2] = StrToInt(val); //пишем последний элемент

//здесь будет код работы с матрицей

for (i = 0; i < n; i++) 
free(matrica[i]); //удаляем сначало массивы чисел (внутренние)
free(matrica); //а затем и массив указателей
UnmapViewOfFile(fmatr); //закрываем
CloseHandle(hFileMap);  //все
CloseHandle(hFile);		 //объекты ядра
return 0;
}
Для работы с файлом я использовал API-фукции для работы с проекцией файла в память. Это позволило рассматривать файл как простую строку (массив типа char). Файл должен содержать правильную информацию, т.е. каждый элемент должен отделяться от другого пробелом, после последнего элемента строки должна идти последовательность \r\n, после последнего элемента последней строки символов быть не должно. Каждая строка должна содержать одинаковое число элементов, равное количеству строк. Иначе код может работать некорректно.
 

Вложения

  • calloc.zip
    9,1 КБ · Просмотры: 226
S

shisik

Только что подумал. Ведь для решения системы метдом Гаусса нужна не квадратная матрица, а столбцов должно быть на 1 больше (для свободных членов)...
 
F

Folderx

Задача сводится как символы
1 12 4 5
из файла превратить в числа
1,12,4,5
убрав пробелы и конец строки

Как 12 (это два символа), превратить в 12 (одну цифру) ?
 
O

Over

Как 12 (это два символа), превратить в 12 (одну цифру) ?
2 Foldrex: во-первых, 12 - это ДВЕ цифры, и одно число
во-2-х. чтобы преобразовать строку в число можно использовать функцию atoi().
 
S

shisik

<!--QuoteBegin-Folderx+6:09:2007, 23:47 -->
<span class="vbquote">(Folderx @ 6:09:2007, 23:47 )</span><!--QuoteEBegin-->Задача сводится как символы
1 12 4 5
из файла превратить в числа
1,12,4,5
убрав пробелы и конец строки[/quote]
По-моему, это всё уже написано :)
 
M

mms

<!--QuoteBegin-shisik+6:09:2007, 16:17 -->
<span class="vbquote">(shisik @ 6:09:2007, 16:17 )</span><!--QuoteEBegin-->Код
int **matrica;
matrica = new int *[n];
for (int i =0; i < n; i++)
matrica = new int[n];
Очищать память следует в обратном порядке:
Код
for (i = 0; i < n; i++)
delete matrica;
delete matrica;
[snapback]77403" rel="nofollow" target="_blank[/snapback]​
[/quote]

Неверно! Учимся удалять массивы:

 
S

shisik

Хоть вы и правы, но это почему-то приводит к ошибке :(
 
F

Folderx

2 Foldrex: во-первых, 12 - это ДВЕ цифры, и одно число
во-2-х. чтобы преобразовать строку в число можно использовать функцию atoi().

А если я не хочу использовать atoi(), как вручную 123 превратить в цифру 123 а не в цифры 1 2 3 ? :(

shisik, написано тут StrToInt(val), а чо это за функция, чо там внутри ?
вот всё что там написано, остальное мусор какой :)
 
N

North

2 shisik

Мапить файл в память - круто. Но лучше все это подымать асинхронно, а затем проталкивать в кеш L1.
И считать естественно только через MMX и SSE, желательно писать интиринсиками :( .

Если серьезно - респект.
 
S

shisik

<!--QuoteBegin-Folderx+7:09:2007, 22:35 -->
<span class="vbquote">(Folderx @ 7:09:2007, 22:35 )</span><!--QuoteEBegin-->написано тут StrToInt(val), а чо это за функция, чо там внутри ?[/quote]

Я не знаю, что там внутри - функция из shlwapi.h А если вы хотите вручную перевести из char* в int, то это будет выглядеть как-то так:
Код:
int MyStrToInt(char *val)
{
int res = 0;
for (int i = 0; i < strlen(val); i++)
switch (val[i]) {
case '0':
res = res * 10;
break;
case '1':
res = res * 10 + 1;
break;
case '2':
res = res * 10 + 2;
break;
case '3':
res = res * 10 + 3;
break;
case '4':
res = res * 10 + 4;
break;
case '5':
res = res * 10 + 5;
break;
case '6':
res = res * 10 + 6;
break;
case '7':
res = res * 10 + 7;
break;
case '8':
res = res * 10 + 8;
break;
case '9':
res = res * 10 + 9;
break;
}
return res;
}
Функция примитивна, но принцип, думаю, ясен :(

Для: North
Ну не знаю, по-моему, проще работать с массивом char, чем читать по 1 байту из файла :)
 
F

Folderx

Число 158

res = 0 * 10;
res = 0 * 10 + 1; // получилось 1
res = 1 * 10 + 5; // получилось 15
res = 15 * 10 + 8; // получилось 158

Количество цифр в числе определяется через strlen() из <string.h>

Терь ясно :(
 
Статус
Закрыто для дальнейших ответов.
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!