2013-10-11 3 views
-1

이 코드를 유지하고 싶습니다하지만 지금은 내 while 루프에서 파일을 읽을 때 방법이 있는지 궁금합니다 내가 그 루프간단한 텍스트 파일에서 읽기 및 선행 공백 및 빈 줄이 제거 된 다른 텍스트 파일에 쓰기

내가 공백 제거에 문제의 톤을 데 내에서 공백을 제거 할 경우이 나를 위해 매우 어려웠다 그래서 내가 할 수있는, 내 프로그램에 파일 읽기에 큰 이해가없는 아무도 내게 말하지 말아요 내 실수를 저질렀습니까?

#include <iostream> 
#include <cassert> 
#include <string> 
#include <fstream> 
#include <cstdio> 

using namespace std; 

int main (void) 
{ 
int i=0; 
int current=0; 
int len; 
int ch; 
string s1; 
string s2; 
ifstream fileIn; 
    cout << "Enter name of file: "; 
    cin >> s1; 
    fileIn.open(s1.data()); 
    assert(fileIn.is_open()); 

while (!(fileIn.eof())) 
    { ch=fileIn.get(); 
    s1.insert(i,1,ch); 
    s1.end(); 
    i++;} 



cout << s1; 
len=s1.length(); 
cout << len; 

while (current < len-1) 
    { 
     if (!(s1[current] == ' ' && s1[current + 1] == ' ') && 
      !(s1[current] == '\n' && s1[current + 1] == '\n') 
      ) 
     { 
      s2.append(s1[current]); 
     } 

     current++; 

    } 

return 0; 
} 
+0

먼저 자신의 기능 대신 [std :: isblank'] (http://en.cppreference.com/w/cpp/string/byte/isblank)를 사용해야합니다. 또한 C++ 표준 라이브러리에는 [알고리즘] (http://en.cppreference.com/w/cpp/algorithm)과 같은 멋진 세트가 있습니다. 예를 들어 ['std :: remove_if'] (http : // en.cppreference.com/w/cpp/algorithm/remove). –

+1

링크를 클릭하십시오. –

+2

주된 문제는 한 번에 한 줄씩 파일을 읽지 않는다는 것입니다.선행 공백 (및 빈 줄)을 제거하려는 경우 필수적입니다. 대신 한 번에 한 글자를 읽는 것입니다. – john

답변

0

표준 라이브러리에는 이미 원하는 대부분의 기능이 있으므로 대부분의 작업을 수행하기 위해 최선을 다할 것입니다. 제거 특정 부분 집합 일부 데이터를 복사

는 어떻게해야 무엇 std::remove_copy_if, 그래서 메인 루프에 사용할 것 : 그 의지하는 line의 적절한 정의를 제공, 그래서

std::remove_copy_if(std::istream_iterator<line>(std::cin), 
     std::istream_iterator<line>(), 
     std::ostream_iterator<std::string>(std::cout, "\n"), 
     [](std::string const &s){return s.empty(); }); 

빈 행을 제거한 행을 복사하십시오.

다음 단계는 line 클래스를 정의하여 스트림에서 하나를 추출 할 때 선행 공백을 제거하고 string으로 변환 할 수 있습니다. 이를 위해 나는 조금 "속임수"를 썼다. mystream >> mychar;과 같은 스트림에서 문자를 추출하면 선행 공백을 자동으로 건너 뜁니다. char를 읽은 다음 그것을 다시 스트림 에 넣음으로써 그것을 사용할 것입니다. 그래서 첫 번째 비 공백 문자에서 시작하는 스트림을 가졌습니다. 그런 다음 나머지 줄을 읽으려면 getline을 사용합니다.

void skip_leading_blanks(std::istream &is){ 
    char ch; 
    is >> ch; 
    is.putback(ch); 
} 
: 문자를 읽기


1. 즉시 스트림에 다시 넣어 코멘트, 또는 skip_leading_blanks 같은 설명이 포함 된 이름과 기능에 투입되는 하나 장점을 충분히 아마 이례적인 일이다

1

나는 다르게 할 일이 많습니다. 세부 사항으로 들어가기없이, 여기 나가 제시하는 무슨이다;

#include <algorithm> 
#include <cctype> 
#include <fstream> 
#include <functional> 
#include <iostream> 
#include <locale> 

using namespace std; 

// trim from left 
static string ltrim(string s) { 
     s.erase(s.begin(), find_if(s.begin(), s.end(), [](char c) { return !isblank(c); })); 
     return s; 
} 

int main() { 

    string file_name; 

    cout << "Please enter the file name: " << flush; 
    cin >> file_name; 

    ifstream in(file_name); 

    if (!in.good()) { 

    cout << "Failed to open file \"" << file_name << "\"" << endl; 

    return 1; 
    } 

    string buffer; 

    while (getline(in, buffer)) { 

    buffer = ltrim(buffer); 

    if (!buffer.empty()) { 

     cout << buffer << '\n'; // <-- or write into a file as you need 
    } 
    } 

    return 0; 
} 

지금은 제목 만 선두 공백을 제거하고 싶지만 내 질문에 당신이 고 응답 말한다 : 그것은 C++ 11 (당신이 GCC 또는 연타를 사용하는 경우 컴파일러도 -std=c++11을 통과)가 필요합니다 선 끝에서 뒤 공백을 제거하려고합니다. 그런 경우 ltrim() 대신 trim()을 사용하십시오. 필요한 기능은 다음과 같습니다.

// trim from left 
static string ltrim(string s) { 
     s.erase(s.begin(), find_if(s.begin(), s.end(), [](char c) { return !isblank(c); })); 
     return s; 
} 

// trim from right 
static string rtrim(string s) { 
     s.erase(find_if(s.rbegin(), s.rend(), [](char c) { return !isblank(c); }).base(), s.end()); 
     return s; 
} 

// trim from both left and right 
static string trim(string s) { 
     return ltrim(rtrim(s)); 
} 

기타 가장 빠른 트림 구현이 있습니다. 예 : What's the best way to trim std::string?

+0

우수 답변. –

+0

@RaviShenoy 감사합니다. 나는 적어도 당신이 그것을 좋아하기 때문에 다행이다. – Ali

관련 문제