2012-05-07 16 views
2

私は、この機能を使用して文字アレイ内のファイルの内容を入れている:文字配列から改行を取り除くには?

void Read::readFile(){ 
FILE * fp = fopen(this->filename,"rt"); 
fseek(fp, 0, SEEK_END); 
long size = ftell(fp); 
fseek(fp, 0, SEEK_SET); 
char *pData = new char[size + 1]; 
fread(pData, sizeof(char), size, fp); 
fclose(fp); 
this->data = pData; 
} 

は、今私は、char-配列からすべての行末を取り除きたいです。 char配列を文字列に最初にキャストせずにこれを行うにはどうすればよいですか?

btw。これは私たちが文字列ライブラリを使用することを許可されていない宿題の一部です。

+6

あなたはCの関数を使用しているのはなぜファイルを読み込むために、文字列クラスを使用してstrinを処理する必要があるのはなぜですかgデータ? –

+0

「ストリップ」とはなんですか?配列全体をコピーして、改行を除いた配列をコピーするか、改行を他の文字に置き換えますか? – Duck

+0

@Duck私はOPがコピー操作をしなくてもいいと思っています – johnathon

答えて

8
#include <algorithm> 
size = std::remove(pData, pData + size, '\n') - pData; 
pData[size] = 0; // optional 

void strip_newlines(char* p) { 
    char* q = p; 
    while (p != 0 && *p != '\0') { 
     if (*p == '\n') { 
      p++; 
      *q = *p; 
     } 
     else { 
      *q++ = *p++; 
     } 
    } 
    *q = '\0'; 
} 
+0

私の考えはまさにです。シンプルでモダンで効果的で効率的。 – chris

+0

シングルライナーソリューションは常に最高のIMO +1です。 – EdChum

+0

他の人には本質的に1ライナーのように見えます。 – chris

1

最も簡単な方法は、2番目のバッファを元の配列のサイズにすることです。

int len = size; 

char* newBufer = calloc(len,sizeof(char)); 
int i = 0; 
int j = 0; 
int nlCount = 0; 

for(i=0; i<len; i++) { 
    if(pData[i] != '\n') { 
    newBuffer[j++] = pData[i]; 
    } else { 
    nlCount++; 
    } 
} 

printf("Finished copying array without newlines. Total newlines removed: %d",nlCount); 

ここで追加の利点は、あなたの配列をmalloc'ingの代わりをcalloc'edので、あなたは(LEN-nlCount)で、データをコピーが完了したら、すべての値は、ので、この場合には、最初はゼロであります〜(len)はすべてゼロ(つまり '\ 0')になるので、文字列のように自動的にヌル文字で終了します。完了したら配列を解放する()ことを忘れないでください。場所の除去で

#include <algorithm> 
size = std::remove_if(pData, pData + size, [](char c) { return c == '\n'; }) - pData; 
pData[size] = 0; // optional 
1

:いくつかのC++ 11のラムダ楽しみのため

+0

無駄な 'size'引数...埋め込まれたNULがある場合はどうなりますか? ''\ n' 'に続く文字を無駄に複数回コピーし、文字列を終了せず、新しいサイズを見つける方法を提供しません。 –

+0

私はforループをやろうとしていたときにそこにサイズを入れました...そしてポインタだけに切り替えました...削除されます。 – Kevin

+0

whileループが完了すると、文字配列の最後に改行文字を追加することを忘れないでください。 – Chisholm

0

このような何か:

void Read::readFile() 
{ 
    FILE * fp = fopen(this->filename,"rt"); 
    if (fp) 
    { 
     char *pData = NULL; 

     fseek(fp, 0, SEEK_END); 
     long size = ftell(fp); 
     if (size != -1L) 
     { 
      pData = new char[size]; 
      if (size > 0) 
      { 
       fseek(fp, 0, SEEK_SET); 
       size = fread(pData, sizeof(char), size, fp); 
      } 
     } 
     fclose(fp); 

     if (size < 0) 
     { 
      delete[] pData; 
      pData = NULL; 
     } 
     else if (size > 0) 
     { 
      char *start = pData; 
      char *end = start + size; 

      char *ptr = (char*) memchr(pData, '\n', size); 
      while (ptr) 
      { 
       int len = 1; 
       if ((ptr > start) && ((*ptr-1) == '\r')) 
       { 
        --ptr; 
        ++len; 
       } 

       memmove(ptr, ptr+len, end - (ptr+len)); 
       end -= len; 

       ptr = (char*) memchr(ptr, '\n', end - ptr); 
      } 

      size = (end - start); 
     } 

     this->data = pData; 
     this->size = size; 
    } 
} 
関連する問題