2016-10-31 18 views
0

私のCプログラムには次の問題があります。その機能の一部は、テキストを読み込んで文に分割し、その文をファイルに書き込むことです。C - Strtok()、 ' n'の文字列を分割しますが、区切り文字はそのままです

私はしかし、同じようにテキストのチャンクで\ n個の文字が含まれている文があるとき(\ nが発生したときに、文が終了)文のテキストのチャンクを分割する)(はstrtokを使用:

は、 //////////////////////////////

こんにちは、これは、これが第二の文

あるいくつかのサンプルテキスト
です

上記の文章は新しい行です。
これは最後の文です。

/////////////////////////////

次のようにファイルの出力は次のとおりです。

0こんにちは、これはいくつかのサンプルテキストです
1これは第2文です
2上記の文章は新しい行です
3これが最後の文です。

///////////////////////////////////////////////////////////////////////////// //////

それがされるべきである:

0こんにちは、これはこれは、第二の文
3いくつかのサンプルテキスト
1になっている上記の文章はちょうど\ nは
です4これが最後の文です。

////////////////////////////////////

すべき文字列を保持するファイルなぜなら、\ nで分割された文章中のテキストの塊を分割しなければならず、各文をファイルに書き込む前に整数を前に付けなければならないからです。

これは、この機能に関連するコードです:

int counter = 0; // Used for counting 
const char s[2] = "\n"; // Used for tokenization 

// ............ 

char *token; 
     token = strtok(input,s); 
     while(token != NULL){ 
     fprintf(logs, "%d ", counter); 
     fprintf(logs, "%s\n" , token); // Add the new line character here since it is removed from the tokenization process 
     counter++; 
     token = strtok(NULL, s); 
     } 

// ......... 

は「空文」(ちょうど\ n個の文字である文は)それを処理するときのための特別なケースを持ってする方法はあります正しく?

strtok()の代わりに別の関数が使用されている可能性はありますか?

+1

私はstrtokでこれを行うことはできません。いくつかのカスタムトークン化コードを使用します。 –

+1

strchr()strpbrk()strstr()strcspn() – joop

+0

文字列を分割するためのカスタムコードを記述しました。レシピ:http://stackoverflow.com/questions/40196067/parse-path-variable-and-save-the-directory-names-into-an-array-of-strings/40196300#40196300 –

答えて

2

コメントが示唆するようにあなたはおそらくstrstrまたはstrchrを使用する必要がありますが、あなたのアプリケーションが何らかの理由でstrtokを必要とする場合、あなたはそれぞれの文の終わりの位置をオフに保存し、複数の改行(\n)が発生したことを決定することができますポインタ演算を順次行います。

ラフ未テストのコード例:

int counter = 0; // Used for counting 
const char* last_sentence; 


// ............ 
     last_sentence = input; 
     char *token; 
     token = strtok(input,"\n"); 
     while(token != NULL){ 
     int i; 
     for (i = (token - last_sentence);i > 1; i--){ 
      // this gets called once for each empty line. 
      fprintf(logs, "%d \n", counter++); 
     } 
     fprintf(logs, "%d %s\n", counter++, token); 

     last_sentence = token + strlen(token); 
     token = strtok(NULL, "\n"); 
     } 

// ......... 

EDIT:あなたが唯一の区切り文字を持たない簡単に、特に以来場合strchrを使用してstrchr

と例を追加しましたが、同様に簡単です。以下のコードはあなたの文章を取り、それらを分割しています。単に印刷するだけですが、目的に合わせて簡単に拡張することができます。

#include <stdio.h> 
#include <string.h> 
const char* sentences = "Hello, this is some sample text\n" 
         "This is the second sentence\n" 
         "\n" 
         "The sentence above is just a new line\n" 
         "This is the last sentence.\n"; 

void parse(const char* input){ 
    char *start, *end; 
    unsigned count = 0; 

    // the cast to (char*) is because i'm going to change the pointer, not because i'm going to change the value. 
    start = end = (char*) input; 

    while((end = strchr(start, '\n'))){ 
     printf("%d %.*s", count++, (int)(end - start + 1), start); 
     start = end + 1; 
    } 
} 

int main(void){ 
    parse(sentences); 
} 
+0

上記のコードは私の実装で正しく動作しているようです!私は手作業で文章を文字で書くようなことをやろうとしましたが、\ nや\ 0を適切に満たすケースは扱いましたが、あなたの解決策ははるかに洗練されています! – Jetmax

+0

@Jetmax、私は 'strchr'を使用した例を追加しました。他の人が触れたように、これはもっと正しい方法です。注意しないとポインタ算術が問題になることがあります。 'strchr'の例は、この場合でもさらに簡単であり、同様に効果的です。 – Mobius

0

ファイルから入力を読み取っている場合は、ストリーム(fopen())を使用し、getline()を使用できます。

これ以外の場合は、\nの数を数え、char*の配列を割り当てて1行ずつ入力します。

EDIT:あなたはそれを自分でコーディングしたくない場合、あなたはいくつかの小さな研究

0

で簡単にそれを見つけることができますあなたはstrtokに設定された区切り文字で改行\nが含まれています。

入力文字列が有効な読み取り値で、strtokの最初の呼び出しでNULLが返された場合は、処理できる空白行です。

token = strtok(input,s); 
if(token == NULL) { 
    fprintf(logs, "%d\n", counter); 
    counter++; 
} 
while(token != NULL){     // the `while` serves as `else` 
    fprintf(logs, "%d ", counter); 
    fprintf(logs, "%s\n" , token); 
    counter++; 
    token = strtok(NULL, s); 
} 
関連する問題