2012-04-09 13 views
0

ich einfaches Programm auf C benötigen ++, die zwei Matrizen aus Textdatei nehmen und es nehmen auch die Anzahl der Zeile und Spalte eines jeden wie folgt aus:lesen Textdatei enthalten Matrix C++

diese ex, für den es Textdatei

3 5 
1 -2 3 4 5 
1 2 -3 4 5 
-1 2 3 4 5 
5 4 
-1 2 3 4 
1 -2 3 4 
1 2 -3 4 
1 2 3 -4 
-1 -2 -3 -4 

die erste Zeile jeder Matrix enthalten `s Anzahl von Zeilen- und Spalten

enthalten und dies ist das prog, die ich versuchte, es zu tun

#include <cstdio> 
#include <cstring> 
#include <fstream> 
#define Height 3 
#define Width 5 
// I assume that each input line in the file can contain at most width * 3 characters. 
// Three extra characters for NL, CR, 0. 
// Change this if you expect the file to contain longer lines. 
#define BUFFER_WIDTH (Width * 3 + 3) 
unsigned char Map[Height][Width]; 
char line[BUFFER_WIDTH]; 
// Remove CR, NL at the end of the line. 
void clean_line(char *line) 
{ 
int len = strlen(line); 
    while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) 
{ 
line[len - 1] = '\0'; 
len--; 
    } 
} 
int main() 
{ 
FILE *fp = fopen("input1.txt","r"); 
int row = 0; 
while (!feof(fp) && row < Height) 
    { 
    fgets(line, BUFFER_WIDTH, fp); 
    clean_line(line); 
    int len = strlen(line); 
    int rowLen = len > Width ? Width : len; 
for (int col = 0; col < rowLen; col++) 
{ 
    Map[row][col] = line[col]; 
    printf("%d ",Map[row][col]); 
} 
printf("\n"); 
row++; 
} 
fclose(fp); 
return 0; 
} 
+3

Welche Programme haben Sie versucht? Es wäre auch gut, wenn Sie erklären würden, welche Art von Datenstruktur Sie gerne lesen würden. – jrok

+0

Wirklich? Sie haben es geschafft, viele Programme zu schreiben, die das nicht tun? Könnten Sie bitte ein Beispiel von mindestens einem von ihnen geben? –

+0

sieht aus wie Hausaufgaben – Yakov

Antwort

1

Sie müssen die Datei als Ganzes analysieren und dann durch ein Delimeter teilen (in diesem Fall Zeilenumbrüche und Leerzeichen). Dieser Vorgang wird Tokenisierung genannt. Viele Bibliotheken wie boost oder poco unterstützen solche Operationen.

class StringTokenizer

boost::split

+0

Ich bearbeitete das Prog jetzt denke ich ist anschaulicher :) – bigner

1
#include <iostream> 

void matUpdate(int***mat,int& row,int& col,int**matData,int& rowData,int& colData) { 
    *mat = matData; 
    row = rowData; 
    col = colData; 
} 
int read(int***mat1,int***mat2,int& row1,int& col1,int& row2,int& col2) 
{ 
    FILE* fp = fopen("mat.txt","r"); 
    if (fp == NULL) { 
     return -1; 
    } 
    int row,col,matNum = 0; 
    while(matNum < 2) { 
     if (fscanf(fp,"%d %d",&row,&col) != 2 || row < 0 || col < 0) { 
      return -1; 
     } 
     int i,j; 
     int** mat = new int*[row]; 

     for (i = 0; i < row;++i) { 
      mat[i] = new int[col]; 
     } 
     for (i = 0;i < row;++i) { 
      for (j = 0;j < col;++j) { 
       fscanf(fp,"%d",&mat[i][j]); 
      } 
     } 
     if (matNum) { 
      matUpdate(mat2,row2,col2,mat,row,col); 
     } 
     else { 
      matUpdate(mat1,row1,col1,mat,row,col); 
     } 
     matNum++; 
    } 
    return fp; 
} 
int main() 
{ 
    int **mat1 = NULL,**mat2 = NULL; 
    int row1,col1,row2,col2; 
    FILE* fp = read(&mat1,&mat2,row1,col1,row2,col2); 
    if (fp != - 1) { 
    //work with matrics 
    //delete memory allocated for matrics 
    fclose(fp); 
    } 
    else { 
     //error 
    } 

} 
+0

Thnx Yakov für Ihre schnelle Replay :) aber die Anzahl der Zeile und Spalte wird in der Textdatei nicht in der Hauptfunktion wie oben in der Frage die erste Zeile in jeder Matrix enthalten es 's Anzahl der Zeile und Spalte – bigner

+0

Ich nehme an, dass vorher Matrix gibt es eine Zeile in der Datei [Anzahl der Zeilen] [Anzahl der Spalten]. Und die Datei enthält 2 Matrizen – Yakov

+0

nein die erste Zeile jeder Matrix, die die Anzahl der Zeilen und Spalten enthalten wird :) und vielen Dank für Ihre schnelle Wiederholung: D – bigner

0
#include <iostream> 
#include <vector> 
using namespace std; 

vector<vector<int>> read_matrix(istream& in) 
{ 
    int rows, cols; 
    in >> rows >> cols; 

    vector<vector<int>> matrix(rows, vector<int>(cols)); 

    for (auto& row : matrix) 
     for (auto& cell : row) 
      in >> cell; 

    return matrix; 
} 

int main() 
{ 
    fstream in("input.txt"); 
    vector<vector<int>> mat1 = read_matrix(in); 
    vector<vector<int>> mat2 = read_matrix(in); 
} 
0

ich eine ziemlich einfache CSV-Reader-Klasse vor kurzem schrieb, das viele der Dinge tut, für den Sie suchen. Ich auch posted this code auf dem Stapel Exchange Code Review. Dies beinhaltet auch einige Kommentare zum Code. Ich verwende boost::MultiArray, um die Ergebnisse in einem 2D-Array zu speichern, und ich verwende boost::split, um den Text in der Datei in Zahlen aufzuteilen. Hier

ist der Code:

Eine Header-Datei:

#include <iostream> 
#include <sstream> 
#include <string> 
#include <stdexcept> 

class BadConversion : public std::runtime_error { 
public: 
    BadConversion(std::string const& s) 
    : std::runtime_error(s) 
    { } 
}; 

class BadIndex : public std::runtime_error { 
public: 
    BadIndex(std::string const& s) 
    : std::runtime_error(s) 
    { } 
}; 

inline double convertToDouble(std::string const& s) 
{ 
    std::istringstream i(s); 
    double x; 
    if (!(i >> x)) 
    throw BadConversion("convertToDouble(\"" + s + "\")"); 
    return x; 
} 

und der C++ Code, der einige Beispiele umfassen verwendet:

#include <iostream> 
#include <sstream> 
#include <fstream> 
#include <string> 
#include <vector> 
#include <boost/algorithm/string.hpp> 
#include <boost/multi_array.hpp> 
#include "csv-test.h" 
#include <cassert> 

template <class T> class csv_reader { 
    boost::multi_array<T, 2> content2d ; 
    std::vector<std::string> split_line ;   
    std::string line; 
    std::string sep ; 
    int ncol ;       
    int nrow ; 
public : 
    csv_reader(std::string, std::string) ; // constructor 
    ~csv_reader();   // desctructor 
    void cout_content() ; // print the contents 
    T operator() (unsigned row, unsigned column) ; 
} ; 

// Constructor 
template <class T> csv_reader<T>::csv_reader(std::string path, std::string sep = ",") 
{ 
    // Initializing variables 
    ncol = 0 ; // Initialize the number of colums to 0 
    nrow = 1 ; // Initialize the number of rows to 1 
    content2d = boost::multi_array<T, 2> (boost::extents[0][0]) ; 
    std::ifstream data(path.c_str()) ; 

    // read the csv data 
    while(getline(data, line)) 
    { 
    boost::split(split_line, line, boost::is_any_of(sep)) ; 
    if(ncol == 0) 
    { 
     ncol = split_line.size() ; 
    } 
    else assert(ncol == split_line.size()) ; 
    content2d.resize(boost::extents[nrow][ncol]) ; 
    for(int i = 0; i < split_line.size(); i++) 
    { 
     content2d[nrow - 1][i] = convertToDouble(split_line[i]) ; 
    } 
    nrow++ ; 
    } 
} 

// Destructor 
template <class T> csv_reader<T>::~csv_reader() { } 

template <class T> void csv_reader<T>::cout_content() 
{ 
    for(int row = 0; row < (nrow - 1); row++) 
    { 
     for(int col = 0; col < ncol ; col++) 
     { 
     std::cout << content2d[row][col] << " "; 
     } 
     std::cout << "\n" ; 
    } 
} 

// Allow access to the contents 
template <class T> T csv_reader<T>::operator() (unsigned row, unsigned column) 
{ 
    if (row >= nrow || column >= ncol) 
    throw BadIndex("boost::MultiArray subscript out of bounds"); 
    return(content2d[row][column]) ; 
} 

int main() 
{ 
    // An integer csv reader 
    csv_reader<int> csv_obj_int("test.csv") ; 
    csv_obj_int.cout_content() ; 

    // A double csv reader 
    csv_reader<double> csv_obj_double("test.csv") ; 
    csv_obj_double.cout_content() ; 

    // It also supports direct access to the content using operator() 
    std::cout << csv_obj_double(1,1) << "\n" ; 
    std::cout << csv_obj_double(1,1) * 5 << "\n" ; 

    // This statement fails with a subscript out of bounds error 
    // std::cout << csv_obj_double(10,10) * 5 << "\n" ; 

    // Testing a different seperator 
    csv_reader<double> csv_obj_double_sep2("test_semicol.csv", ";") ; 
    csv_obj_double_sep2.cout_content() ; 
}