2012-06-26 3 views
0
struct DataValue 
{ 
    DataValue() : uiQuality(0) {} // Here 0 stands for good. 
    unsigned int uiQuality; 
    std::string  timeChanged; 
    float   value; 
}; 

std::vector<DataValues> myDataValues 

내 응용 프로그램의 어느 시점에서 내 벡터의 데이터가 채워집니다. 아래 파일을 사용하여 쓰고 있습니다.파일에서 데이터 읽기 및 STL 벡터 채우기

std::ofstream myfile("myData.txt", std::ios::app); 

for (int j = 0; j < myDataValues.size(); j++) 
{ 
    std::string quality; 
    if(myDataValues[j].quality == 0) { 
     quality = "good"; 
    } 
    else { 
     quality = "bad"; 
    } 
    myfile << myDataValues[j].timeChanged.c_str() << " " << myDataValues[j].value << " " << quality << std::endl; 
} 

파일은 다음과 같습니다.

2012-06-25 12:41:56.789 55 good 
2012-06-25 12:51:14.782 55 good 
2012-06-25 05:25:16.456 62.6925 good 
2012-06-25 05:26:11.458 63.4109 good 
2012-06-25 05:27:01.459 63.0383 good 
2012-06-25 05:27:56.959 61.5266 good 
2012-06-25 05:29:01.959 58.5354 good 
2012-06-25 05:32:06.963 47.5656 good 
2012-06-25 05:33:06.964 44.9916 good 
2012-06-25 05:33:11.963 44.8267 good 
2012-06-25 05:34:06.965 43.6011 good 
2012-06-25 05:34:56.965 43.493 good 
2012-06-25 12:51:14.782 52.418 good 
2012-06-25 09:49:54.112 0 good 
2012-06-25 11:50:30.781 0 good 

위의 파일을 다른 응용 프로그램에서 읽고 다른 벡터를 채워야합니다. 채우기 벡터 wheter 중복 또는이 검사가 필요하지 않습니다.

std::vector<DataValues> anotherDataValues 

샘플 코드 요청 위의 파일에서 데이터를 읽고 위의 벡터를 채우려면 어떻게해야합니까?

어떻게 효과적으로 처리 할 수 ​​있습니까?

시간과 도움에 감사드립니다.

+0

복제본이 있지만 주요 아이디어는 다음과 같습니다. (머리 위로) : std :: vector anotherDataValues ​​(std :: ostream_iterator (fileObject, ""), std :: ostream_iterator ()); ' – chris

+0

벡터를 채우는 동안 복제본을 검사 할 필요없이 단순히 데이터 f를 읽으십시오. ROM 파일과 벡터 읽기 당신은 elobaorate 주실 래요? – venkysmarty

+0

나는 질문의 중복을 의미했다; 나는 최근에 몇 가지를 보았다. 이 코드는 'ostream_iterator'를 시작과 끝 위치로 사용하여 벡터를 문자열의 벡터로 효과적으로 읽도록 벡터를 대략 초기화합니다. 간단히 말해서, 같은 일을하는 짧은 루프처럼 이해하기 쉽지 않은 하나의 라이너입니다. – chris

답변

2

확실한 방법은 클래스에 대한 >> (및 <<) 연산자를 작성하는 것입니다. 당신이 거래를해야하기 때문에,

std::copy(myDataValues.begin(), myDataValues.end(), 
      std::ostream_iterator<DataValue>(myFile, "\n")); 

<< 운영자가 조금 까다 롭습니다 : 출력 할 수있는, 간단하게 작성하여 배열

std::ostream& 
operator<<(std::ostream& dest, DataValue const& data) 
{ 
    dest << data.timeChanged << " " 
     << data.value << " " 
     << (data.uiQuality == 0 ? "good" : "bad"); 
    return dest; 
} 

당신이 이런 짓을하면 : 삽입 조작은 매우 간단합니다 형식에서 가능한 오류가 있습니다. 데이터 형식이 공백이 포함되어 있음을 감안할 때, 나는 터미네이터로`\ n을 '을 부과하고, 같은 것을 할 거라고 : 날짜 형식의 공백이 일을 복잡하게하는 것이

std::istream& 
operator>>(std::istream& source, DataValue& dest) 
{ 
    std::string line; 
    if (std::getline(source, line)) { 
     std::istringstream parse(line); 
     std::string date; 
     std::string time; 
     float value; 
     std::string status; 
     parse >> date >> time >> value >> status >> std::ws; 
     if (! parse || (status != "good" && status != "bad")) { 
      source.setstate(std::ios_base::failbit); 
     } else { 
      dest.timeChanged = date + ' ' + time; 
      dest.value = value; 
      dest.uiQuality = (status == "good" ? 0 : 1); 
     } 
    } 
    return source; 
} 

참고. 만약 당신이 형식에 대한 몇 가지 컨트롤을 가지고, 나는 그것을 없애 버릴거야.예를 들어, ISO는 을 사용하여 날짜와 시간을 구분합니다.) 일종의 DataTime을 사용하면 효과가 있습니다. 이 클래스는 물론 이 자체적으로 >><<을 제공합니다. 그런 다음 위에서 사용할 수 있습니다. 이 작업을 완료하면

, 독서는 사소한뿐만 아니라이된다 :

std::vector<DataValue> v(
    (std::istream_iterator<DataValue>(myFile)), 
    (std::istream_iterator<DataValue>())); 

(. 가장 embaressing 구문 분석 문제를 방지하기 위해 인수 중 적어도 하나에 필요한 여분의 괄호를 참고.)

0

분명히 stl 벡터에서 push_back 수 있습니다. 그러나, 당신이 그것을하고 있다면, 그리고 얼마나 벡터에 대해 알고. reserve 함수를 사용하여 벡터의 크기를 조정할 필요가 없도록 충분한 공간을 요청할 수도 있습니다. 또는 resize 함수 호출을 사용하고 이미 필요한 크기의 stl 벡터를 채울 수 있습니다.

http://www.cplusplus.com/reference/stl/vector/

당신은 또한 당신이 먼저 하나 DataValue 개체를 읽을 수있는 방법을 파악해야한다 ifstream의 getline 기능

http://www.cplusplus.com/reference/iostream/istream/getline/

+0

나는 같은 장소에서 푸시 백해서는 안됩니다. 다른 응용 프로그램에서 파일을 읽는 중입니다. – venkysmarty

1

에서 데이터를 얻을 수 있습니다. 그런 다음 벡터를 채우는 것은 쉽습니다. 그 방법은 다음과 같습니다 (보다 포괄적 인 오류 검사를 제공해야 함).

std::istream & operator>>(std::istream & is, DataValue & dv) { 
    std::string date, time, quality; 
    float value; 
    if (is >> date >> time >> value >> quality) { 
     if (quality == "good") 
      dv.uiQuality = 0; 
     else if (quality == "bad") 
      dv.uiQuality = 1; 
     else { 
      is.setstate(std::ios::failbit); 
      return is; 
     } 
     dv.timeChanged = date + " " + time; 
     dv.value = value; 
    } 
    return is; 
} 

그런 다음 다음과 같이 단순히 벡터를 채울 수 :

std::ifstream fin("myData.txt"); 
std::istream_iterator<DataValue> beg(fin), end; 
std::vector<DataValue> v(beg,end);