2010-04-26 5 views
1

입력 파일, 출력 파일 및 지정되지 않은 단어 수와 같은 명령 줄 인수를 사용하는 프로그램을 작성하는 연습을 완료하려고합니다. 프로그램은 입력 파일의 내용을 한 줄 한 줄씩 읽고 단어가 들어있는 줄을 찾은 다음 줄 번호가있는 줄을 출력 파일에 인쇄합니다. 여기 내 코드는 다음과 같습니다.파일 한 줄씩 읽는 데 문제가 있습니다.

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

int main(int argc, char* argv[]) { 
    if (argc < 4) { 
     cerr << "Error #1: not enough arguments provided\n"; 
     return 1; 
    } 
    ifstream in(argv[1]); 
    if (!in.is_open()) { 
     cerr << "Error #2: input file could not be opened\n"; 
     return 2; 
    } 
    ofstream out(argv[2]); 
    if (!out.is_open()) { 
     cerr << "Error #3: output file could not be opened\n"; 
     return 3; 
    } 
    ostringstream oss; 
    for (int i = 3; i < argc; ++i) { 
     int k = 0; 
     string temp; 
     oss << argv[i] << ":\n\n"; 
     while (getline(in, temp)) { 
      ++k; 
      unsigned x = temp.find(argv[i]); 
      if (x != string::npos) 
       oss << "Line #" << k << ": " << temp << endl; 
     } 
    } 
    string copy = oss.str(); 
    out << copy; 
    in.close(); 
    out.close(); 
    return 0; 
} 

실행하려고하면 예상되는 첫 번째 단어의 예상 출력이 나오지만 다음 단어는 발견되지 않습니다. 이다

in: 

Line #1: #include <iostream> 
Line #2: #include <fstream> 
Line #3: #include <string> 
Line #4: #include <sstream> 
Line #5: using namespace std; 
Line #7: int main(int argc, char* argv[]) { 
Line #12:  ifstream in(argv[1]); 
Line #13:  if (!in.is_open()) { 
Line #14:   cerr << "Error #2: input file could not be opened\n"; 
Line #22:  ostringstream oss; 
Line #23:  string temp; 
Line #24:  for (int i = 3; i < argc; ++i) { 
Line #26:   int k = 0; 
Line #28:   while (getline(in, temp)) { 
Line #30:    unsigned x = temp.find(argv[i]); 
Line #31:    if (x != string::npos) 
Line #32:     oss << "Line #" << k << ": " << temp << endl; 
Line #35:  string copy = oss.str(); 
Line #37:  in.close(); 
out: 

, 그것은 처음 주어진 단어가 아니라 어떤 다음의 모든 인스턴스를 찾을 수 있습니다 : 예를 들어, 소스 코드에 대한 위의 다음과 같은 출력을 제공 할 것입니다. 여기서 내가 뭘 잘못하고 있니?

편집 : 나는 파일의 시작 부분으로 돌아갈 방법을 찾아 내려고 노력했지만, 나는 "rewind()"또는 이와 비슷한 방법을 찾지 못해서 포기했다. while 루프 이후에 in.seekg(0, ios::beg)을 추가했는데 여전히 잘못된 출력을 제공합니다.

EDIT 2 : 좋아, 마침내 포기하고 실현 쌍의 벡터를 사용하여 야생 일종의 시도하지 않고 내 원래의 원하는 출력을 얻을 수 없을 것이다, 그래서 포기하고 그것을 결정하기

found in at line #31:   cerr << "Error #2: input file could not be opened\n"; 
found out at line #34:  ofstream out(argv[2]); 

즉, 모든 행을 순서대로 인쇄하고 각 단어를 발견 한 특정 단어로 향하게합니다. while 루프는 다음과 같습니다.

ostringstream oss; 
string temp; 
while(getline(in,temp)) { 
    static int count = 1; 
    for (int i = 3; i < argc; ++i) { 
     unsigned foundWord = temp.find(argv[i]); 
     if (foundWord != string::npos) 
      oss << "found " << argv[i] << " at line #" << count << ": " << temp << endl; 
    } 
    ++count; 
} 

어쨌든 모든 도움에 감사드립니다! 운동 그 자체는 결과가 어떤 식 으로든 포맷되어야한다고 말하지 않았으므로 완전히 완성 된 것으로 간주합니다.

+0

+1은'exit'보다는'main' 함수에서'return'을 사용합니다. –

+0

여기를 보시려면 http://stackoverflow.com/questions/2712076/에'using namespace std'를 사용하지 말아야 할 이유가 있습니다. – sbi

+0

아, 네임 스페이스 오염이 나쁘다는 것을 알고 있습니다. 나는이 작은 운동을 위해 그것을 사용하는 습관에 불과합니다. – Maulrus

답변

3

찾고있는 문자열을 반복하고 있지만 루프의 파일을 읽는 getline()이 있습니다. 당신이 정말로 원하는 :

for each input line 
    getline 
    for each string we are looking for 
     is string in line? 
+0

고마워, 이건 정말 내게 필요한 것을 생각 나게했다. – Maulrus

5

i=3에서 파일은 내부 while(getline()) 루프의 EOF로 읽습니다. 따라서 i=4,5,6…에 파일을 더 이상 읽을 수 없습니다.

당신이 하나 필요 rewind 처음부터 다시 입력 파일 내부 루프가 종료 또는 루프의 순서를 전환 이후에 (while(getline(...)) { ... for (int i = 3; ...) { ... } ... })

0

내 생각 엔 당신이의 시작 부분에 파일 포인터를 재설정해야한다는 것입니다 for 루프를 통해 매번 파일을 입력하십시오. 지금은 루프 외부에서 한 번 열어 다음 단어에 대한 시작 부분으로 다시 설정하는 메카닉이 없습니다.

1

당신은 다시 읽기 전에 파일의 시작 부분에 되감기 기능 in.seekg (0, ios::beg);을 사용할 수 있습니다.

0

스트림을 되감 으려면 먼저 in.clear()을 호출하여 스트림의 상태 플래그를 설정 해제해야합니다. 이 작업을 수행 한 후에 만 ​​in.seekg(0, ios::beg)으로 전화하여 get 위치를 처음으로 되돌릴 수 있습니다.

0

@Neils answer은 알고리즘에 결함이 있음을 나타냅니다. 그의 의사 코드는 좋은 출발점입니다. 나는 당신이 그것을 취하고 각 단계를 좀 더 상세한 의사 코드로 작성하려고 노력할 것을 제안한다.의사 코드가 실제 코드로 쉽게 변환 될 때까지 반복해서 수행하십시오. 이 접근법은 매우 유용하며, 나중에 발생할 수있는보다 복잡한 문제에 대해서도 유용합니다. Sarcastically 말하기 전에 코드를 작성하십시오.

힌트 찾고있는 단어를 데이터 구조에 저장하여 반복적으로 반복 할 수 있도록하는 것이 좋습니다.

+0

고마워, 나는 쉬운 길을 찾고 있었다고 생각하지만, 분명히 올바르게하는 것이 낫다. argv [3]에서 단어 구조를 유지하는 것 이상으로 단어를 유지하지는 않습니까? – Maulrus

관련 문제