2010-03-29 32 views
11

gì là lựa chọn tốt nhất nếu tôi muốn "nâng cấp" cũ C-mã để C mới hơn ++ khi đọc một tập tin với một dấu phân cách dấu chấm phẩy:Kiểu tương đương hiện đại (C++) cho phương thức fscanf cũ hơn (kiểu C) là gì?

/* reading in from file C-like: */ 
fscanf(tFile, "%d", &mypost.nr); /*delimiter ; */ 
fscanf(tFile, " ;%[^;];", mypost.aftername);/* delimiter ; */ 
fscanf(tFile, " %[^;]", mypost.forename); /*delimiter ; */ 
fscanf(tFile, " ;%[^;];", mypost.dept);/*delimiter ; */ 
fscanf(tFile, " %[^;];", mypost.position);/* delimiter ; */ 
fscanf(tFile, "%d", &mypost.nr2); 

//eqivalent best C++ method achieving the same thing? 
+0

Tôi tự hỏi fscanf nghiêm ngặt như thế nào? Nếu bạn đọc tất cả các ký tự lên đến dấu chấm phẩy trên dòng có tên, thì dòng tiếp theo có thể đọc một dấu cách trước dấu chấm phẩy như thế nào? - Ngoài ra, 'fscanf' có thể sẽ không tệ nếu bạn cũng có thể chỉ định số ký tự tối đa để đọc ở đâu đó. – UncleBens

Trả lời

11

Bạn có thể nạp chồng toán tử phải thay đổi trên istream cho struct của bạn , vì vậy:

std::istream& operator>>(std::istream& is, mypost_struct& mps) { 
    is >> mps.nr; 
    is.ignore(1, ';'); 
    is.getline(mps.forename, 255, ';'); 
    is.getline(mps.aftername, 255, ';'); 
    is >> mps.dept; 
    is.ignore(1, ';'); 
    is >> mps.position; 
    is.ignore(1, ';'); 
    is >> mps.nr2; 

    return is; 
} 

Sau đó, đầu vào cũng đơn giản như is >> mypost;, nơi is là file mà bạn đã mở.

Chỉnh sửa: @UncleBens Cảm ơn bạn đã chỉ ra điều này, tôi đã quên mất không gian trong tài khoản. Tôi đã cập nhật câu trả lời, giả sử rằng forename và aftername có khả năng chứa không gian. Và có này chút thay embarrasing về delimiters là dụng dấu ngoặc kép ...

tôi chỉ kiểm tra nó bằng một định nghĩa struct như dưới:

struct mypost_struct { 
    int nr; 
    char forename[255], aftername[255]; 
    int dept, position, nr2; 
}; 

.. và kết quả là như mong đợi.

+0

Tôi tự hỏi những gì tất cả các upvotes là cho. Ý tưởng cung cấp quá tải '>>' là tốt nhưng việc thực hiện (** cách ** đọc đầu vào phân tách) hoàn toàn bị hỏng. 'ignore' không có dạng này, và thậm chí nếu bạn sửa nó, điều này sẽ không thay đổi hành vi của' istream.operator >> 'và sử dụng"; " như một dấu phân cách. Nó sẽ sắp xếp công việc nếu đầu vào cũng được phân tách bằng khoảng trắng và không có chuỗi nào chứa nhiều hơn một từ. – UncleBens

+0

Cảm ơn bạn đã chỉ ra điều này :) – susmits

3

Như @susmits nói, nhưng bạn cũng có thể sử dụng dòng trở lại như một điều kiện, như:

if (is >> mps.nr && is.ignore(1, ";") && is >> mps.aftername && ...) { 
    // all is well ... 
} else { 
    // bad input format 
} 

hoặc thậm chí:

if (is >> mps.nr >> ignore(";") >> mps.aftername >> ...) { 
    // all is well ... 
} else { 
    // bad input format 
} 
1

gì là lựa chọn tốt nhất nếu tôi muốn để "nâng cấp" C-code cũ lên C++ mới hơn ...?

IMHO, cách tốt nhất để làm điều này là đọc tệp theo từng dòng và sử dụng regular expressions for parsing.

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