2009-09-25 57 views
16

Làm thế nào để đọc dữ liệu từ một tập tin nếu tập tin của tôi là như thế này với Comma Separated Values ​​Làm thế nào để đọc-viết vào/từ tập tin văn bản với các giá trị dấu phẩy tách

1, 2, 3, 4, 5\n 
6, 7, 8, 9, 10\n 
\n 

và sau khi đọc các tập tin, tôi muốn để ghi dữ liệu trở lại vào tệp khác với cùng định dạng ở trên.

Tôi có thể lấy tổng số dòng, sử dụng

string line; 
while(!file.eof()){ 
     getline(file,line); 
     numlines++; 
    } 
    numline--; // remove the last empty line 

nhưng làm thế nào tôi có thể biết tổng số chữ số trong một hàng/dòng ??

Tôi cũng có vectơ ints để lưu trữ dữ liệu. Vì vậy, tôi muốn đọc dòng đầu tiên và sau đó đếm tổng số phần tử trong dòng đó, ở đây 5 (1,2,3,4,5) và lưu trữ chúng trong mảng/vector và đọc dòng tiếp theo và lưu chúng trong vector một lần nữa và như vậy cho đến khi tôi đạt EOF.

Sau đó, tôi muốn viết dữ liệu vào tập tin, một lần nữa, tôi đoán đây sẽ làm công việc viết dữ liệu vào tập tin,

numOfCols=1; 
for(int i = 0; i < vector.size(); i++) 
{ 
    file << vector.at(i); 
    if((numOfCols<5) file << ",";//print comma (,) 
    if((i+1)%5==0) 
    { 
        file << endl;//print newline after 5th value 
        numOfCols=1;//start from column 1 again, for the next line 
    } 
    numOfCols++; 
} 
file << endl;// last new line 

Vì vậy, vấn đề chính của tôi là làm thế nào để đọc dữ liệu từ tệp với giá trị được phân cách bằng dấu phẩy ??

Cảm ơn

Trả lời

24

Bước 1: Đừng làm điều này:

while(!file.eof()) 
{ 
    getline(file,line); 
    numlines++; 
} 
numline--; 

Các EOF là không đúng sự thật cho đến khi bạn cố gắng và đọc qua nó. Mẫu chuẩn là:

while(getline(file,line)) 
{ 
    ++numline; 
} 

Cũng lưu ý rằng std :: getline() có thể tùy chọn lấy tham số thứ ba. Đây là nhân vật để đột nhập. Theo mặc định, đây là trình kết thúc dòng nhưng bạn có thể chỉ định dấu phẩy.

while(getline(file,line)) 
{ 
    std::stringstream linestream(line); 
    std::string   value; 

    while(getline(linestream,value,',')) 
    { 
     std::cout << "Value(" << value << ")\n"; 
    } 
    std::cout << "Line Finished" << std::endl; 

} 

Nếu bạn lưu trữ tất cả các giá trị trong một véc tơ, sau đó in chúng ra bằng chiều rộng cố định. Sau đó, tôi sẽ làm một cái gì đó như thế này.

struct LineWriter 
{ 
     LineWriter(std::ostream& str,int size) 
       :m_str(str) 
       ,m_size(size) 
       ,m_current(0) 
     {} 

     // The std::copy() does assignement to an iterator. 
     // This looks like this (*result) = <value>; 
     // So overide the operator * and the operator = to 
     LineWriter& operator*() {return *this;} 
     void operator=(int val) 
     { 
       ++m_current; 
       m_str << val << (((m_current % m_size) == 0)?"\n":","); 
     } 

     // std::copy() increments the iterator. But this is not usfull here 
     // so just implement too empty methods to handle the increment. 
     void operator++()  {} 
     void operator++(int) {} 

     // Local data. 
     std::ostream&   m_str; 
     int const    m_size; 
     int      m_current; 
}; 

void printCommaSepFixedSizeLinesFromVector(std::vector const& data,int linesize) 
{ 
    std::copy(data.begin(),data.end(),LineWriter(std::cout,linesize)); 
} 
+0

Điều này làm gì? std :: linestream linestream (line); – Curious

+0

Nó tạo ra một đối tượng dòng chuỗi. Nó hoạt động giống như một dòng, như std :: cin, std :: cout hoặc một luồng tệp std :: fstream, nhưng sử dụng một chuỗi làm nguồn dữ liệu. Vì vậy, trong thực tế nó là một dòng chỉ là một dòng. –

+0

Khi tôi cố gắng biên dịch, tôi nhận được lỗi này, biến 'std :: stringstream linestream 'có bộ khởi tạo nhưng không đầy đủ. Tôi đã bao gồm tất cả tiêu đề bắt buộc. – Curious

0

Thử lớp stringstream:

#include <sstream> 

Chỉ trong trường hợp, nhìn lên Stroustrup của "The C++ Programming Language Special Edition" trang 641 ví dụ.

Nó làm việc cho tôi và tôi đã có một thời gian cố gắng để tìm ra điều này.

5

tại đây tôi đăng mã để đọc CSV cũng như viết mã. Tôi đã kiểm tra tiền phạt hoạt động của nó.

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <vector> 
using namespace std; 

void readCSV(istream &input, vector< vector<string> > &output) 
{ 
    string csvLine; 
    // read every line from the stream 
    while(getline(input, csvLine)) 
    { 
      istringstream csvStream(csvLine); 
      vector<string> csvColumn; 
      string csvElement; 
      // read every element from the line that is seperated by commas 
      // and put it into the vector or strings 
      while(getline(csvStream, csvElement, ',')) 
      { 
        csvColumn.push_back(csvElement); 
      } 
      output.push_back(csvColumn); 
    } 
} 

int main() 
{ 
    ofstream myfile; 
    string a; 
    fstream file("b.csv", ios::in); 
    myfile.open ("ab.csv"); 
    if(!file.is_open()) 
    { 
      cout << "File not found!\n"; 
      return 1; 
    } 
    // typedef to save typing for the following object 
    typedef vector< vector<string> > csvVector; 
    csvVector csvData; 

    readCSV(file, csvData); 
    // print out read data to prove reading worked 
    for(csvVector::iterator i = csvData.begin(); i != csvData.end(); ++i) 
    { 
      for(vector<string>::iterator j = i->begin(); j != i->end(); ++j) 
      { 
      a=*j; 
        cout << a << " "; 
      myfile <<a<<","; 

} 
myfile <<"\n"; 
cout << "\n"; 
} 
myfile.close(); 
system("pause"); 

} 
Các vấn đề liên quan