2010-07-16 37 views
18

Tôi có một std :: istream đó đề cập đến dữ liệu ma trận, một cái gì đó như:C++ đọc từ istream cho đến khi xuống dòng (nhưng không phải khoảng trắng)

0.0 1.0 2.0 
3.0 4.0 5.0 

Bây giờ, để đánh giá số lượng cột Tôi muốn có một số mã như:

std::vector<double> vec; 
double x; 
while((...something...) && (istream >> x)) 
{ 
    vec.push_back(x); 
} 
//Here vec should contain 0.0, 1.0 and 2.0 

nơi ... một cái gì đó ... một phần là false sau khi tôi đọc 2.0 và istream tại điểm nên có 3.0 để tiếp theo

istream >> x; 

phải đặt x bằng 3.0.

Bạn sẽ đạt được kết quả này như thế nào? Tôi đoán rằng điều kiện trong khi

Cảm ơn bạn rất nhiều trước sự giúp đỡ của bạn!

+0

Chỉ cần làm rõ, lý do tôi muốn theo đuổi cách tiếp cận này (nếu có thể làm được) là tránh tạo các đối tượng tạm thời (ngoài x đôi). Ma trận sau đó được tạo bởi std :: swap - ing vectơ ở trên với bộ nhớ trong ma trận (nó được thực hiện thông qua một std :: vector). – stepelu

+0

tốt, bạn có thể làm điều đó với một tạm thời trong 10 dòng đơn giản, hoặc bạn có thể làm điều đó mà không có tạm thời trong 50 dòng cứng. Sử dụng tạm thời. –

Trả lời

12

Sử dụng phương pháp peek để kiểm tra nhân vật tiếp theo:

while ((istream.peek()!='\n') && (istream>>x)) 
+3

Điều này có thể dễ dàng bị hỏng nếu dòng chứa * bất kỳ * khoảng trắng trước Clifford

+0

True; không có kiểm tra lỗi ở tất cả ở đây, tôi chỉ giả định đầu vào được định dạng tốt. – tzaman

6

Đọc các dòng thành chuỗi tiêu chuẩn :: sử dụng std::getline(), sau đó gán chuỗi cho đối tượng std::istringstream và trích xuất dữ liệu từ đó thay vì trực tiếp từ istream.

+0

Xin lỗi tôi đã không làm điều này rõ ràng nhưng đây là những gì tôi đang cố gắng để tránh. Điểm là tôi không biết trước nếu ma trận là sẽ có nhiều cols hoặc nhiều hàng và có chuỗi cửa hàng 10.000 đôi không phải là một sự phê duyệt rất hiệu quả cho vấn đề :) Xin lỗi một lần nữa vì không làm cho điều này rõ ràng, lỗi của tôi. – stepelu

0

Đọc số, sau đó đọc một ký tự để xem đó là dòng mới hay chưa.

1

Bạn có thể sử dụng std::istream::peek() để kiểm tra xem ký tự tiếp theo có phải là dòng mới hay không. Xem this entry trong tham chiếu cplusplus.com.

2
std::vector<double> vec; 
{ 
    std::string line; 
    std::getline(ifile, line); 
    std::istringstream is(line); 
    std::copy(std::istream_iterator<double>(is), std::istream_iterator<double>(), 
       std::back_inserter(vec)); 
} 
std::cout << "Input has " << vec.size() << " columns." << std::endl; 
std::cout << "Read values are: "; 
std::copy(vec.begin(), vec.end(), 
      std::ostream_iterator<double>(std::cout, " ")); 
std::cout << std::endl; 
+0

OP được đề cập cụ thể không muốn đệm toàn bộ dòng đầu tiên. – tzaman

+0

Yêu cầu mã được đề xuất của anh ta sau thời gian vector phải chứa dòng đầu tiên: '// Ở đây vec nên chứa 0,0, 1.0 và 2.0'. Anh ta không muốn đọc một dòng hay toàn bộ tập tin? –

+0

Có Tôi muốn kết thúc vòng lặp while sau khi dòng đầu tiên đã được đọc (và giữ phần còn lại trong istream để đọc thêm) nhưng tôi muốn tránh phải tạo chuỗi để lưu toàn bộ dòng đầu tiên trước khi đưa nó vào vectơ . – stepelu

0

Tôi có vấn đề tương tự
Input là như sau:

1 2 
3 4 5 

The 1st hai là N1 và N2
Sau đó, có một dòng mới
rồi đến các phần tử 3 4 5, tôi không t biết có bao nhiêu cái này sẽ được.

// read N1 & N2 using cin 
int N1, N2; 
cin >> N1; 
cin >> N2; 

// skip the new line which is after N2 (i.e; 2 value in 1st line) 
cin.ignore(numeric_limits<streamsize>::max(), '\n'); 

// now read 3 4 5 elements 
int ele; 
// 2nd EOF condition may required, 
// depending on if you dont have last new-line, and it is end of file. 
while ((cin_.peek() != '\n') && (cin_.peek() != EOF)) { 
    cin >> ele; 
    // do something with ele 
} 

Điều này làm việc hoàn hảo cho tôi.

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