2014-03-31 3 views
0

학교 프로젝트의 일환으로 인벤토리 * .txt 파일을 C++의 배열로 가져 와서 나중에 * .txt 파일로 가져오고 싶습니다. 프로그램.C++ 텍스트 파일을 다차원 배열 문제로 변환

텍스트 파일은 식료품 이야기 항목을 나타내는 10 개의 행으로 시작하고 항목의 이름, 가격 및 수량을 나타내는 세 개의 열을 포함합니다. 나는 파일에서 읽을 수 있었고 심지어 표시되는 각 행 앞에 번호를 추가했습니다. 이제는 "직원"사용자가 항목을 한 번에 하나씩 변경할 수 있도록 텍스트 파일을 문자열 배열로 가져온 다음 해당 배열을 다시 * .txt 파일로 덤프 할 수 있습니다.

아래 코드는 지금까지 내가 시도한 코드입니다. 파일에서 행 수를 얻을 수는 있지만 계산 된 열 또는 표시된 행의 데이터를 가져올 수 없습니다. 프로그램을 실행하면 행 (10)과 Cols (0)가 표시된 후 10 개의 빈 줄이 표시됩니다.

* .txt 파일의 열은 일반적으로 공백으로 구분됩니다. 나는 탭을 시도하고 시도 : 방금 ​​내가 추측하고있는 콘솔을 표시하기 위해 메모리 주소가 있었고 충돌이 발생했습니다.

불행히도, 우리는 프로그램을 디버깅하는 데별로 익숙하지 않았으며, 강의 계획서에서 보면 완전히 철저히 다루지 않을 것이라고 생각합니다. 그래서 더 이상 문제를 해결할 방법을 모르겠습니다. 나는 지난 몇 시간 동안 Google-ing을 보냈으며 실제로 도움을 요청할 필요가 있음을 알게되었습니다.

프로젝트에는이 구성 요소보다 훨씬 많은 내용이 포함되어 있지만 실제로이 부분에 집착하고 있습니다. 나는 나를 위해이 일을 할 누군가를 요구하는 것이 아니지만, 누군가 내가 뭘 잘못하고 있고 다차원 배열로 텍스트 파일을 얻으려고 최선의 방향으로 나를 가리킬 수 있다면, 나는 정말로 감사 할 것이다.

감사합니다.

#include <iostream> 
    #include <fstream> 
    #include <iomanip> 
    #include <string> 
    #include <sstream> 
    #include <array> 


    int row = 0; 
    int col = 0; 

    using namespace std; 

    int main() 
    { 
     string lines; 
     int x; 
     string textArray[2][2]; 
     ifstream invFile; 
     invFile.open("inventory.txt"); 

     if(invFile.fail()){ 
      cerr << "The file cannot be opened!"; 
      exit(1); 
     } 

     cout << "\n" << endl; 
     while(invFile.good()) { 

      while(getline(invFile, lines)) { 
       istringstream streamA(lines); 
       col = 0; 
       while(streamA >> x) { 
        cout << x; 
        textArray[row][col] = x; 
        col++; 
       } 
       row++; 
      } 
     } 

     invFile.close(); 

     cout << "Rows: " << row << endl; 
     cout << "Cols: " << col << endl; 
     cout << "\n" << endl; 

     for(int i=0; i<row; i++){ 
      for(int j=0; j<col; j++){ 
       cout << "Line: " << i << textArray[i][j] << "."; 
      } 
      cout << "\n"; 
     } 

     return(0); 
    } 
============================= 
    inventory.txt: 

    Apples 1.25 20 
    Oranges 1.75 20 
    Kiwi 2.50 15 
    Pineapples 5.50 20 
    Tomatoes 1.50 20 
    Onions 2.00 20 
    Corn 1.80 20 
    Carrots 2.30 20 
    Milk 4.50 20 
    Cheese 2.25 20 
+1

두 가지 문제점이 있습니다. 첫 번째 변수는'x' 변수의 타입입니다. 예를 들어 "Oranges"는 숫자로 분석 할 수 없으며 첫 번째 시도에서'while (streamA >> x)'가 실패하게됩니다. 두 번째 문제는'textArray' 선언입니다. 배열 경계는 사용자가 보유한 데이터를 저장하기에 충분하지 않습니다. 'textArray [20] [3]'을 사용하는 것이 효과적 일지 모르지만 왜 그 이유가 무엇인지 이해해야합니다. – msandiford

+0

두 번째 문장을 보았을 때 나는 그것을 때리고 나서 몇 시간 동안 상처받을 것이라고 생각합니다! 나는 이것을 몇 시간 동안 보았고, x의 데이터 타입을 제외하고는 모든 것을 좌우로 바꿨다. 나는 정수 목록을 문자열로 바꾸는 것을 잊어 버렸다. 이전 테스트에서 배열 크기가 더 큽니다. 일단 10으로 다시 이동하고 x를 문자열로 변경하면 모든 것이 완벽하게 작동합니다. 정말 고맙습니다! – jayvee

답변

1

- 나는 빠른 & 좋은 "디버그"방법도 생각한다. 그래서 당신은 당신이 쉽게 잘못을 찾을 수 있습니다. 코드에서 예를 들어, textArray가 할당되지 않은 것 같다, 그래서 근처에 약간의 인쇄를 추가

while(getline(invFile, lines)) { 
       cout <<"lines: " << lines << endl; //test enter here 
       istringstream streamA(lines); 
       col = 0; 
       while(streamA >> x) { 
        cout << "x is" << x; //test if enter here 
        textArray[row][col] = x; 
        col++; 
       } 
       row++; 
      } 

를 출력을 통해 선이 괜찮습니다하지만 cout << "x is" << x;while(streamA >>x) 조건이 거짓 즉, 인쇄되지 않았다, 왜?

이동, 그것은, int에 무리한 assing Applesstd::istringstreamx 1 개 값이 Apples, operator << 돌아갑니다 NULL입니다 INT 타입하지만, COL, 라이브러리의 함수가 호출 찾을 때까지 지금 발견 점 1. 만약 int을 사용하거나 float 숫자를 저장하려면 atoi, atof과 같은 일부 변환 API를 사용하십시오.

변경 후 에서 int에서 string으로 바뀌 었습니다. 분명히 textArray [2] [2]는 모든 정보를 저장하기에 충분하지 않습니다. "범위를 벗어남"은 분할 오류의 원인이므로 통과 할 때까지 계속 테스트 할 대형 배열을 만듭니다.

1

당신이 할 수있는 몇 가지 방법이 있습니다. 가장 쉬운 방법은 파일의 맨 위에 3,10과 같은 것을 넣는 것입니다. 그러면 3 개의 열과 10 개의 행을 알 수 있습니다. 이 글을 수정 한 후에 쓰면, 그 숫자가 정확하게 쓰여지는지 확인해야 할 것입니다.

좀 더 진보 된 방법을 배우고 싶다면 더 많은 것을 배운 후에 더 쉽게 생활 할 수 있습니다.

당신이 단지 stringstream에 읽을 수 vector< vector<string> > 같은 것을 사용하여 벡터를 사용하고 읽을 줄을 분할 벡터

fstream file(...); 
string tempString; 
vector< vector<string> > list; 

// Get a full line 
while(getline(file, tempString, '\n'){ 

    // Create a StringStream and store tempString in it for further manipulation 
    stringstream ss; 
    ss << tempString; 
    vector<string> tempVec; 

    // Get each column from this row 
    while(getline(ss, tempString, '\t'){ 
     // Put each column into a vector 
     tempVec.push_back(tempString); 
    } 

    // Put the entire vector into our list vector 
    list.push_back(tempVec); 
} 

에이 두 번째 방법의 장점을 넣어 경우

은 두 가지이다. 첫째, 매우 쉽습니다. 나는 당신이 어떻게 작동하는지 알지 못한다고 생각하지만, 당신이 모르는 키워드에 대한 쉬운 Google 검색을 수행하면 충분히 빨리 찾을 수 있습니다. 두 번째는 (이론적으로) 무제한 행과 제한되지 않은 열을 허용한다는 것입니다. 이것으로 한 열에 20 개의 열이 있고 한 열에 2가있을 수 있으며 낭비되는 공간이 없다는 것을 의미합니다.

내가 연구하기 전에 설명한 스켈레톤 코드를 사용하면 안됩니다. 여기서 일어나는 일에 대한 일반적인 생각이 없다면 나중에 문제를 일으킬 것입니다. 나는 다른 사람들이 이미 그것을했기 때문에 여기에 모든 것을 설명하지는 않을 것입니다. 또한, 학교에서 이것을 배우고 있기 때문에, 결국 이러한 것들에 도달하게 될 것이기 때문에 앞으로 나아갈 것입니다. 하나의 주된 제약은 프로젝트에 배열이 필요한 경우입니다.이 경우 첫 번째 솔루션이 가장 좋습니다.

+0

최근에 벡터를 다루었는데, 나는 그다지 편안하지 않았습니다. 나는 좋은 연습이 될 것이기 때문에 나는 이것을 시도 할 것이라고 생각한다. 감사. – jayvee

3

데이터를 보유하기 위해 struct 또는 class을 생성하는 것이 좋습니다. 각 텍스트 줄에서 적절하게 필드를 추출하고 struct에 붙여 넣으십시오. 그런 다음 std::vector을 사용하여 해당 목록을 struct 개로 유지하십시오.

#include <iostream> 
#include <fstream> 
#include <iomanip> 
#include <string> 
#include <sstream> 
#include <array> 
#include <vector> 
#include <cstdlib> 

using namespace std; 

struct Row 
{ 
    vector<string> columns; 
}; 

int main() 
{ 
    string line; 
    vector<Row> rows; 
    ifstream invFile; 
    invFile.open("inventory.txt"); 

    if(invFile.fail()){ 
     cerr << "The file cannot be opened!"; 
     exit(1); 
    } 

    cout << "\n" << endl; 
    while(invFile.good()) { 

     while(getline(invFile, line)) 
     { 
      Row row; 
      istringstream streamA(line); 
      string col; 
      while (streamA >> col) 
      { 
      row.columns.push_back(col); 
      } 
      rows.push_back(row); 
     } 
    } 

    invFile.close(); 

    cout << "Rows: " << rows.size() << endl; 
    cout << "Cols: " << rows[0].columns.size() << endl; 
    cout << "\n" << endl; 

    for(int i=0; i<rows.size(); i++){ 
     for(int j=0; j<rows[i].columns.size(); j++){ 
      cout << "Line: " << i << " " << rows[i].columns[j] << "\n"; 
     } 
     cout << "\n"; 
    } 

    return(0); 
} 
난 당신이 중요한 단계에서 일부 인쇄 라인 추가 제안하고 싶습니다
+0

우리는 곧 그것에 대해 배우고 있으며, 내가 본 것에서는 더 잘 작동해야합니다. 불행히도 나는 지금까지 우리가 다루었던 것을 고수해야한다. 감사. – jayvee