ifstream
으로 연 파일에서 현재 줄의 줄 번호를 얻는 가장 좋은 방법은 무엇입니까? 그래서 데이터를 읽었고 데이터가 사양과 일치하지 않을 때 나중에 표시 할 수 있도록 행 번호를 저장해야합니다.C++에서 파일의 행 번호를 가져 오는 방법은 무엇입니까?
10
A
답변
9
ifstream 관점에서 볼 때 줄 번호가 없습니다. 파일을 한 줄씩 읽는다면, 그 파일을 직접 추적하면됩니다.
4
std::getline
을 사용하면 하나씩 차례대로 읽을 수 있습니다. 읽은 행의 수를 나타내는 정수를 유지하십시오 : 0으로 초기화하고 std::getline
을 호출 할 때마다 성공하고 증분하십시오.
8
은 다음 std::streambuf
에서 파생 된 클래스를 사용할 수 std::getline
에 자신을 제한하지 당신이 경우, 어느 현재 행 번호를 추적 유지 :
class CountingStreamBuffer : public std::streambuf { /* see below */ };
// open file
std::ifstream file("somefile.txt");
// "pipe" through counting stream buffer
CountingStreamBuffer cntstreambuf(file.rdbuf());
std::istream is(&cntstreambuf);
// sample usage
is >> x >> y >> z;
cout << "At line " << cntstreambuf.lineNumber();
std::getline(is, str);
cout << "At line " << cntstreambuf.lineNumber();
여기
이입니다 CountingStreamBuffer
의 샘플 구현 :
#include <streambuf>
class CountingStreamBuffer : public std::streambuf
{
public:
// constructor
CountingStreamBuffer(std::streambuf* sbuf) :
streamBuf_(sbuf),
lineNumber_(1),
lastLineNumber_(1),
column_(0),
prevColumn_(static_cast<unsigned int>(-1)),
filePos_(0)
{
}
// Get current line number
unsigned int lineNumber() const { return lineNumber_; }
// Get line number of previously read character
unsigned int prevLineNumber() const { return lastLineNumber_; }
// Get current column
unsigned int column() const { return column_; }
// Get file position
std::streamsize filepos() const { return filePos_; }
protected:
CountingStreamBuffer(const CountingStreamBuffer&);
CountingStreamBuffer& operator=(const CountingStreamBuffer&);
// extract next character from stream w/o advancing read pos
std::streambuf::int_type underflow()
{
return streamBuf_->sgetc();
}
// extract next character from stream
std::streambuf::int_type uflow()
{
int_type rc = streamBuf_->sbumpc();
lastLineNumber_ = lineNumber_;
if (traits_type::eq_int_type(rc, traits_type::to_int_type('\n')))
{
++lineNumber_;
prevColumn_ = column_ + 1;
column_ = static_cast<unsigned int>(-1);
}
++column_;
++filePos_;
return rc;
}
// put back last character
std::streambuf::int_type pbackfail(std::streambuf::int_type c)
{
if (traits_type::eq_int_type(c, traits_type::to_int_type('\n')))
{
--lineNumber_;
lastLineNumber_ = lineNumber_;
column_ = prevColumn_;
prevColumn_ = 0;
}
--column_;
--filePos_;
if (c != traits_type::eof())
return streamBuf_->sputbackc(traits_type::to_char_type(c));
else
return streamBuf_->sungetc();
}
// change position by offset, according to way and mode
virtual std::ios::pos_type seekoff(std::ios::off_type pos,
std::ios_base::seekdir dir,
std::ios_base::openmode mode)
{
if (dir == std::ios_base::beg
&& pos == static_cast<std::ios::off_type>(0))
{
lastLineNumber_ = 1;
lineNumber_ = 1;
column_ = 0;
prevColumn_ = static_cast<unsigned int>(-1);
filePos_ = 0;
return streamBuf_->pubseekoff(pos, dir, mode);
}
else
return std::streambuf::seekoff(pos, dir, mode);
}
// change to specified position, according to mode
virtual std::ios::pos_type seekpos(std::ios::pos_type pos,
std::ios_base::openmode mode)
{
if (pos == static_cast<std::ios::pos_type>(0))
{
lastLineNumber_ = 1;
lineNumber_ = 1;
column_ = 0;
prevColumn_ = static_cast<unsigned int>(-1);
filePos_ = 0;
return streamBuf_->pubseekpos(pos, mode);
}
else
return std::streambuf::seekpos(pos, mode);
}
private:
std::streambuf* streamBuf_; // hosted streambuffer
unsigned int lineNumber_; // current line number
unsigned int lastLineNumber_;// line number of last read character
unsigned int column_; // current column
unsigned int prevColumn_; // previous column
std::streamsize filePos_; // file position
};
0
비효율적하지만 죽은 간단한 방법이다 스트림을 받으면 스트림의 시작 부분에서 현재 위치까지 새 줄 문자를 계산하는 함수가 있습니다. 여러 스트림 위치에 대한 행을 알고 싶다면 매번 스트림 시작부터 계산을 시작하여 여러 번 호출해야하므로 비효율적입니다. 내가 작업하고있는 일부 코드에서 유효하지 않은 입력이있는 경우 줄 번호를 알고 싶습니다.이 경우 가져 오기가 즉시 중단됩니다. 이 함수는 일단 비효율이 실제로 문제가되지 않으면 호출됩니다. 방법의
int getCurrentLine(std::istream& is)
{
int lineCount = 1;
is.clear(); // need to clear error bits otherwise tellg returns -1.
auto originalPos = is.tellg();
if (originalPos < 0)
return -1;
is.seekg(0);
char c;
while ((is.tellg() < originalPos) && is.get(c))
{
if (c == '\n') ++lineCount;
}
return lineCount;
}
장점 중 하나는 변경이 스트림이 구성되어 장소에 필요하지 않습니다이다
, 당신은 당신이 그것을 필요로하는 함수를 호출 할 필요가 : 여기 은 이러한 작업을 수행하기위한 내 코드입니다 .#include <iostream>
#include <sstream>
int getCurrentLine(std::istream& is)
{
int lineCount = 1;
is.clear(); // need to clear error bits otherwise tellg returns -1.
auto originalPos = is.tellg();
if (originalPos < 0)
return -1;
is.seekg(0);
char c;
while ((is.tellg() < originalPos) && is.get(c))
{
if (c == '\n') ++lineCount;
}
return lineCount;
}
void ReadDataFromStream(std::istream& s)
{
double x, y, z;
while (!s.fail() && !s.eof())
{
s >> x >> y >> z;
if (!s.fail())
std::cout << x << "," << y << "," << z << "\n";
}
if (s.fail())
std::cout << "Error at line: " << getCurrentLine(s) << "\n";
else
std::cout << "Read until line: " << getCurrentLine(s) << "\n";
}
int main(int argc, char* argv[])
{
std::stringstream s;
s << "0.0 0.0 0.0\n";
s << "1.0 ??? 0.0\n";
s << "0.0 1.0 0.0\n";
ReadDataFromStream(s);
std::stringstream s2;
s2 << "0.0 0.0 0.0\n";
s2 << "1.0 0.0 0.0\n";
s2 << "0.0 1.0 0.0";
ReadDataFromStream(s2);
return 0;
}
관련 문제
- 1. Perl을 사용하여 파일의 현재 행 번호를 가져 오는 방법은 무엇입니까?
- 2. 입력에서 문장 번호를 가져 오는 방법은 무엇입니까?
- 3. 연락처 번호를 텍스트보기로 가져 오는 방법은 무엇입니까?
- 4. 현재 줄 번호를 가져 오는 방법은 무엇입니까?
- 5. C#의 TextBox에서 커서의 열 번호를 가져 오는 방법은 무엇입니까?
- 6. 어셈블리를로드하지 않고 버전을 가져 오는 방법은 무엇입니까?
- 7. 예외가 발생한 행 번호를 가져 오는 방법이 있습니까?
- 8. gridview에서 하이퍼 링크 필드의 행 번호를 가져 오는 것이 가능합니까?
- 9. 가져 오는 행 번호 -
- 10. 가져 오는 행
- 11. 주소록에서 전화 번호를 문자열로 가져 오는 방법은 무엇입니까?
- 12. 내보내기 후 현재 개정 번호를 파일로 가져 오는 방법은 무엇입니까?
- 13. SQL Server 2000 쿼리에서 현재 행 번호를 가져 오는 방법은 무엇입니까?
- 14. struts1의 displaytag 열 중 하나의 체크 박스에 현재 페이지 행 번호를 가져 오는 방법은 무엇입니까?
- 15. PostgreSQL 쿼리에서 행 번호를 표시하는 방법은 무엇입니까?
- 16. C에서 Windows의 파일 핸들에서 파일 이름을 가져 오는 방법은 무엇입니까?
- 17. 데이터베이스에서 데이터를 가져 오는 방법 그러나 정확한 행에서 데이터를 가져 오는 방법은 무엇입니까?
- 18. Gridview 행 값의 텍스트 상자를 가져 오는 방법은 무엇입니까?
- 19. MouseEvent에서 JTable의 행 인덱스를 안정적으로 가져 오는 방법은 무엇입니까?
- 20. Main.mxml 파일의 id 값을 CustomPanel.mxml 파일로 가져 오는 방법은 무엇입니까?
- 21. 폴더 구조에서 모든 파일의 목록을 가져 오는 방법은 무엇입니까?
- 22. rtf 문서 파일의 파일 목록에서 InputStream을 가져 오는 방법은 무엇입니까?
- 23. Java에서 텍스트 파일의 끝 부분을 효율적으로 가져 오는 방법은 무엇입니까?
- 24. 가젯에서 .tar.gz 파일의 압축을 해제하고 가져 오는 방법은 무엇입니까?
- 25. C#에서 파일의 메타 데이터를 가져 오는 방법은 무엇입니까?
- 26. 디렉토리에 ESY 확장자가있는 모든 파일의 목록을 가져 오는 방법은 무엇입니까?
- 27. PL/SQL 사용하기 파일의 내용을 BLOB로 가져 오는 방법은 무엇입니까?
- 28. ASP.NET : 제네릭 처리기에서 파일의 가상 경로를 가져 오는 방법은 무엇입니까?
- 29. .h 파일의 함수를 가져 오는 ctags를 얻는 방법은 무엇입니까?
- 30. 폴더 안에있는 파일의 날짜 시간을 가져 오는 방법은 무엇입니까?
주 : 다음은 전체 예제 당신이 중 하나에 의해 통과'\ n' 문자의 수를 계산 라인으로 라인 ('표준 : getline') 또는 간단하게 읽을 수 있습니다. –
@Matthieu : 각'\ n'이 플랫폼에서 개행을 의미한다고 가정합니다. – rubenvb
@rubenvb : 텍스트 모드에서'\ n'은 줄 바꿈을 나타내며, 'iostream'은 로케일을 사용하여 그것을 만듭니다 (양쪽 모두의 읽기 쓰기). 물론 바이너리 모드로 읽는다면 변환은 일어나지 않습니다 ... –