Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > чтение матриц из файла


Автор: antoshka1303 19.6.2008, 21:15
Есть текстовый файл, в нем расположено н-ое количество матриц.
Матрицы в файле все одной размерности, разделен строчкой, начинающийся с символа @.
То есть, например файла
Код

@1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 
1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 
1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 
1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 
1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 
1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 
1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 
1 1 1 0 0 1 0 0 0 0 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
@2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 
1 1 0 0 0 0 1 0 0 1 1 1 1 1 1 1 
1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 
1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 
1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 
1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 
1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 
1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 0 0 0 0 0 0 0 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
@3
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 
1 1 1 1 1 0 0 1 1 0 0 1 1 1 1 1 
1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 
1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 
1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 
1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 
1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 
1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 
1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 
1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 
1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 
1 1 1 1 0 0 0 0 0 0 0 0 0 1 1 1 
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1



В общем случае количество матриц может быть сколько угодно и размер может быть у матрицы какой угодно (тогда он должен задаваться в параметрах функции). Задача состоит в том, чтобы считать все матрицы, которые находятся в файле в переменные.
У меня получилось все очень только для статического случая, то есть когда заранее известно, сколько в файле матриц.Еще у меня дикий недочет, что я считываю все подряд из файла, включая строчки, начинающиеся с "@" в массив
Код

int W[255][255]

Подскажите, как сделать чтобы можно было просто "идти по файлу" и, увидя символ в строке "@", пропускать эту строчку и далее считывать следующие 16 строк в массив - матрицу?
Код

void makematrixfromfile(char *textFile, int iii)
{
Form1->Journal->Lines->Add(IntToStr(iii));
Form1->Journal->Lines->Add(" ");
int lines = countdoginfile(textFile, '@'); 
/*
int countdoginfile(char * text_file){
    FILE *F;
    int  i, j, p, count = 0;
    char buf[255];
    double x;
    F = fopen(text_file, "r");
        if( F==NULL )
        {
                AnsiString tmp="невозможно открыть файл";
                AnsiString tmp1=text_file;
                AnsiString text=tmp+text_file;
                ShowMessage(text);
                }
        else
{
        char stemp[256], s[2];

       while (!feof(F)){
       fgets(stemp, 256, F);
              if (stemp[0]=='@') count++;
       }
 }
fclose(F);
    return count;
}

*/


if (lines !=3)
{
ShowMessage( "ERROR" );
}

else
{
    int i, j;
        char buf[255];
        int W[255][255];
        FILE* f=fopen(textFile, "r");
        AnsiString text1;
        if (f == NULL){
                    Form1->Journal->Lines->Add("Ошибка открытия файла, его путь:");
                    Form1->Journal->Lines->Add(textFile);
        }
        else
        {
                for( int j = 0; j < (16*3+3); j++ ){
                                fgets(buf, 255, f);
                                W[j][0]=atoi(&buf[0]);
                                W[j][1]=atoi(&buf[2]);
                                W[j][2]=atoi(&buf[4]);
                                W[j][3]=atoi(&buf[6]);
                                W[j][4]=atoi(&buf[8]);
                                W[j][5]=atoi(&buf[10]);
                                W[j][6]=atoi(&buf[12]);
                                W[j][7]=atoi(&buf[14]);
                                W[j][8]=atoi(&buf[16]);
                                W[j][9]=atoi(&buf[18]);
                                W[j][10]=atoi(&buf[20]);
                                W[j][11]=atoi(&buf[22]);
                                W[j][12]=atoi(&buf[24]);
                                W[j][13]=atoi(&buf[26]);
                                W[j][14]=atoi(&buf[28]);
                                W[j][15]=atoi(&buf[30]);

                }

        }
         fclose(f);
}
}


Заранее спасибо за помощь!

Автор: bsa 19.6.2008, 21:58
Код
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <algorithm>

typedef std::vector< std::vector<int> > Matrix;
typedef std::vector<Matrix> MatrixArray;

/* читает открывает файл fileName и читает его содержимое в массив матриц array
*/
void loadMatrices(const std::string &fileName, MatrixArray &array)
{
   std::ifstream file(fileName.c_str());
   Matrix *current = 0;
   std::string buffer;
   while(file.good()) { //пока файл можно читать...
       std::getline(file, buffer); //читаем текстовую строку в буфер
       if (buffer.empty()) //пустая строка?
          continue; //пропускаем пустые строки
       if (buffer[0] == '@') { //начало следующей матрицы
           array.push_back( Matrix() ); //создаем матрицу и помещаем в конец массива
           current = &array.back(); //присваеваем ее адрес указателю current
           continue; //больше эту строку не разбираем
       }
       if (current != 0) {
           std::istringstream str(buffer); //делаем поток из текстовой строки
           Matrix::value_type row; //запись эквивалентна этой: std::vector<int> row;
           std::copy(std::istream_iterator<int>(str), std::istream_iterator<int>(), std::back_inserter(row)); //читаем строку матрицы из потока
           current->push_back(row); //добавляем строку в текущую матрицу
       }
   }
}

Автор: antoshka1303 19.6.2008, 23:47
можете пояснить  несколько моментов? Я с векторами раньше не работал.
Код

 if (buffer[0] == '@') { //начало следующей матрицы      

//я правильно понимаю, что  мы строчку, начинающуюся с '@'  не считываем?
Код

           array.push_back( Matrix() ); //создаем матрицу и помещаем в конец массива

//я правильно понимаю, что   Matrix()  - это какая-то  функция?   если так, то что она возвращает?

           current = &array.back(); //присваиваем ее адрес указателю current
           continue; //больше эту строку не разбираем
       }
просьба детально пояснить вот это
Код

       if (current != 0) {
           std::istringstream str(buffer); //делаем поток из текстовой строки
           Matrix::value_type row; //запись эквивалентна этой: std::vector<int> row;
           std::copy(std::istream_iterator<int>(str), std::istream_iterator<int>(), std::back_inserter(row)); //читаем строку матрицы из потока
           current->push_back(row); //добавляем строку в текущую матрицу
       }

Автор: bsa 20.6.2008, 00:04
antoshka1303
Строку начинающуюся на @ мы читаем, как и все остальные. Только если в начале нее стоит собака, то создаем новую матрицу и переходим на начало цикла (на чтение следующей строки).
Matrix() - это вызов конструктора класса Matrix. Результатом работы является объект класса Matrix.

Остальное здесь:
http://www.cplusplus.com/reference/iostream/istringstream/
http://www.sgi.com/tech/stl/Vector.html
http://www.sgi.com/tech/stl/copy.html
http://www.sgi.com/tech/stl/back_insert_iterator.html
http://www.sgi.com/tech/stl/istream_iterator.html

Автор: antoshka1303 20.6.2008, 00:25
Цитата(bsa @ 19.6.2008,  22:04)
antoshka1303
Строку начинающуюся на @ мы читаем, как и все остальные. Только если в начале нее стоит собака, то создаем новую матрицу и переходим на начало цикла (на чтение следующей строки).
Matrix() - это вызов конструктора класса Matrix. Результатом работы является объект класса Matrix.

Остальное здесь:
http://www.cplusplus.com/reference/iostream/istringstream/
http://www.sgi.com/tech/stl/Vector.html
http://www.sgi.com/tech/stl/copy.html
http://www.sgi.com/tech/stl/back_insert_iterator.html
http://www.sgi.com/tech/stl/istream_iterator.html

класс Matrix  -   ятак понимаю  - стандартный класс библиотеки STL?

Автор: bsa 20.6.2008, 07:45
Цитата(antoshka1303 @ 20.6.2008,  00:25)
класс Matrix  -   ятак понимаю  - стандартный класс библиотеки STL?

Вот так выглядит строка 8 в моем коде:
Код
typedef std::vector< std::vector<int> > Matrix;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)