2014-12-02 1 views
0

사용자로부터 입력을 읽고 계산을 위해 행렬로 변환하는 데 어려움이 있습니다. 예를 들어, input = {1 2 3/4 5 6}으로, 프로그램은 3 COLS 2 개 행이C++에서 행렬에 사용자 입력

1 2 3 
4 5 6 

형태 행렬에서 읽어야한다. 내가 뭘 작동하지 않는 지금까지 가지고 :

input.replace(input.begin(), input.end(), '/', ' '); 
    stringstream ss(input); 
    string token; 
    while (getline(ss, token, ' ')) 
    { 
     for (int i = 0; i < row; i++) 
     { 
      for (int j = 0; j < col; j++) 
      { 
       int tok = atoi(token.c_str()); 
       (*matrix).setElement(i, j, tok);     
      } 
     } 
    } 

것은 그래서 난 할 노력하고있어 토큰에 입력 휴식 및 행의 수를 걸릴 setElement 기능을 사용하여 매트릭스로 저장하는 것입니다 , 열 및 사용자가 저장하고자하는 변수가 포함됩니다. 이 코드의 잘못된 점은 tok 변수가 변경되어 0에 달라 붙는 것으로 보입니다. 행과 열을 알고 있다고 가정합니다.

도움을 주셔서 대단히 감사드립니다.

+0

는 '//' '\ n을'로 교체 시도 할 수 있도록

std::istream& operator>>(std::istream& s, Matrix& m) { return s >> readmatrix(m); } 

같은 형식의 입력 연산자를 추가이 필요한 방법으로 소스 라인을 중단합니다 . –

답변

0

입력에서 읽은 각 문자에 대해 행렬의 각 셀을 조작하려고합니다! 여러 셀이 아닌 각 셀마다 하나의 char을 가져와야합니다.

토큰의 문자열 분할은 다음 기능을 사용하여 수행 할 수 있습니다. 다음 코드가 실행 가능하지 않다는 사실에 놀라지 마십시오. 이는 누락 된 행렬 클래스 때문입니다.

는 다음을보십시오 : 당신은 당신이 실제로의 getline 필요하지 않습니다 포핸드에 행렬의 크기를 알고있는 경우

#include <iostream> 
#include <string> 
#include <sstream> 
#include <algorithm> 
#include <iterator> 

using namespace std; 

void split(const string& str, char delimiter, vector<string>& result) { 
    string::size_type i = 0; 
    string::size_type delimOcc = str.find(delimiter); 

    while (delimOcc != string::npos) { 
     result.push_back(str.substr(i, delimOcc-i)); 
     i = ++delimOcc; 
     delimOcc = str.find(delimiter, delimOcc); 

     if (delimOcc == string::npos) { 
     result.push_back(str.substr(i, str.length())); 
     } 
    } 
} 

int main() 
{ 
    std::string input = "1 2 3/4 5 6"; 

    vector<string> rows; 
    split(input, '/', rows); 

    for(int i = 0; i < rows.size(); i++) { 
     vector<string> cols; 
     split(rows[i], ' ', cols); 

     for(int j = 0; j < cols.size(); j++) { 
      if(cols[j][0] != '\0'){ 
       int tok = stoi(cols[j]); 
       (*matrix).setElement(i, j, tok); 
       cout << tok << " - " << i << " - " << j << endl; 
      } 
      else { 
       if(j == 0) j--; 
      } 
     } 
    } 

    return 0; 
} 
0

, 당신은 INT에 의해 INT 읽어야합니다. 내가 "포맷 입력"의 문제보다 일반적인 파악할 수 있도록 해보자 (테스트되지 않은 코드) 많은 간단한 방법이지만

input.replace(input.begin(), input.end(), '/', '\n'); 
stringstream ss(input); 
for (int i = 0; i < row; i++) 
{ 
    for (int j = 0; j < col; j++) 
    { 
     int tok; 
     ss >> tok; 
     (*matrix).setElement(i, j, tok);     
    } 
} 
1

특정 문제를 해결하기 위해 존재하는 (그리고 다른 대답은 여러 가지 좋은 제안이). 당신이 행을 이해 (복합 형식을 구문 분석해야하고, higer 수준에서 번호 변환

  • 에 문자열을 할 필요가 낮은 수준 소련군의

    1. :

      여기에 문제의 세 가지 종류의 본질적있다 라인 분리)

    2. 마침내 당신은 또한 화합물의 크기를 (이 3 가지가 완전히 독립적이지와 마지막 n은 얼마나 많은 행과 COLS?)

    이해해야한다 (어떻게 행렬의 크기를 결정합니까?)

    마지막으로 네 번째 문제가 있습니다. 즉, 다른 모든 3 가지 문제가 있습니다. 입력이 "잘못"인 경우 어떻게해야할까요?

    은 문제의이 종류는 일반적으로 두 개의 반대 방법으로 여유됩니다

    1. 그들이 와서, 데이터를 읽어 형식이 일치하는 경우 인식하고 동적으로 포함하거나 데이터 구조를 성장 ..
    2. 모든 데이터를 그대로 (텍스트 형식) 읽은 다음 텍스트를 분석하여 얼마나 많은 요소가 있는지 파악한 다음 "청크"를 분리하고 변환합니다.

    포인트 2. 좋은 문자열 조작을 필요로하지만, 또한 입력이 분리 공간 중 하나는 새로운 라인 인 경우 어떻게되는지?를 모든 것이 getline으로 가지고있는 생각 (긴 방법을 알 수있는 능력이 필요 그러한 경우 실패합니다.

    포인트 1은 읽는 동안 커질 수있는 클래스 또는 적절한 동적 인 구조 (예 : std 컨테이너)를 필요로합니다.이 컨테이너에서는 읽은 것을 적절한 위치로 보내기 전에 배치 할 수 있습니다.

    매트릭스가 어떻게 작동하는지 모르겠으므로 임시 벡터를 저장하고 라인을 저장하도록 보냅시다. 이제

    #include <vector> 
    #include <iostream> 
    #include <cassert> 
    
    class readmatrix 
    { 
        std::vector<int> data; //storage 
        size_t rows, cols; //the counted rows and columns 
        size_t col; //the counting cols in a current row 
    
        Matrix& mtx; //refer to thematrix that has to be read 
    public: 
    
        // just keep the reference to the destination 
        readmatrix(Matrix& m) :data(), rows(), cols(), cols(), mtx(m) 
        {} 
    
        // make this class a istream-->istream functors let it be usable as a stream 
        // maniopulator: input >> readmatrix(yourmatrix) 
        std::istream& operator()(std::istream& s) 
        { 
         if(s) //if we can read 
         { 
          char c=0: 
          s >> c; //get a char. 
          if(c!='{') //not an open brace 
          { s.setstate(s.failbit); return s; } //report the format failure 
          while(s) //loop on rows (will break win the '}' will be found) 
          { 
           col=0; 
           while(s) //loop on cols (will break when the '/' or '}' will be found) 
           { 
            c=0; s >> c; 
            if(c=='/' || c=='}') //row finished? 
            { 
             if(!cols) cols=col; //got first row length 
             else if(cols != col) //it appears row have different length 
             { s.setstate(s.failbit); return s; } //report the format failure 
             if(c!='/') s.unget(); //push the char back for later 
             break; //row finished 
            } 
            s.unget(); //pushthe "not /" char back 
            int x; s >> x; //get an integer 
            if(!s) return s; //failed to read an integer! 
            ++col; data.push_back(x); //save the read data 
           } 
           ++rows; //got an entire row 
           c=0; s >> c; 
           if(c == '}') break; //finished the rows 
           else s.unget(); //push back the char: next row begin 
          } 
         } 
         //now, if read was successful, 
         // we can dispatch the data into the final destination 
         if(s) 
         {   
          mtx.setsize(rows,cols); // I assume you can set the matrix size this way 
          auto it = data.begin(); //will scan the inner vector 
          for(size_t r=0; r<rows; ++r) for(size_t c=0; c<cols; ++c, ++it) 
           mtx(r,c) = *it; //place the data 
          assert(it == data.end()); //this must be true if counting have gone right 
         } 
         return s; 
        } 
    }; 
    

    당신이

    input >> readmatrix(matrix); 
    

    당신은 코드의 특정 반복 패턴이 있다는 것을이 시점에서 알 같은 행렬을 읽을 수는 : 하나의 패스는 구문 분석이 전형적인이며, 그 패턴은 수 서브 파서를 구성하기 위해서 그룹화 할 필요가 있습니다. 실제로 그렇게한다면 실질적으로 - boost::spirit을 다시 쓸 것입니다.

    은 물론 약간의 적응은 매트릭스가 작동하는 방식에 따라 할 수있는 행의 크기 (부분 열 충전 ??)

    당신은 수 일치하지 않는 경우 수행하는, 또는 무엇을 (그것은 고정 된 크기 ??있다) 심지어 그냥

    input >> matrix;