2017-09-07 15 views
0

スペースやタブで区切られた数字と挿入する数字の量を含む文字列(char配列)を取得する再帰関数を構築しようとしていますが、各数値をint配列に挿入します。 この関数にはループを使用できません。再帰のみを使用できます。 2つの数字間の空白とタブの数は不明です。 (ただし、char配列は1000文字のバッファです) 入力文字列にgets_sを使用しています。 文字列に間違った文字がある場合、または挿入された数字の数が正しくない場合、関数はエラーを出力し、それ自体を再起動します(再びループがありません)。 +/-符号と先頭のゼロ(001)は許可されます。スペースで区切られた数字の文字列をint配列に変換する

これまでのところ、有効な数値を含むchar配列を取得し、その値をintとして返します(たとえば、{'-','1','5','\0'}-15を返します)。

私のプログラムでこの配列を次に使用するには、文字列をint配列に変換する最良の方法は何ですか?

おかげ

+0

"何が最善の方法です..."ループを使用するには: – Lundin

+1

この種の"解決に最も適したツールを使用しない "問題は、あなたにとっては赤い旗でなければならず、あなたのリソースは何であれ、不適切な方法で問題を解決するよう教えています。実際のところ、ここでCでループを使用しない人はいますか?また、関数型プログラミングを教授したいと思ったら、なぜ非機能型言語を使うのでしょうか?**より良い本を手に入れよう!** – Sebivor

答えて

0

はあなたの終わり関数sだけでなく、文字列内の現在の文字へのポインタを引数として整数配列へのポインタを渡します。空白でない場合は、数値をint配列に追加し、intポインタをインクリメントします。可変長のcharポインタをインクリメントして再帰させる。私は、文字列をint型に変換することができると仮定します。

0

sscanfは、必要なツールのようです。それは私が使用するものです。あなたの文字列をあなたのint配列に再帰的に読み込むことができます。私は501の位置を持つint配列を作成します。これは、取得できるintの最大量です(各intが単一桁の数字であり、その間にスペースが1つしかない場合)。

代わりに私が書いたコメントの中でatoi

1

を使用することができます。

にあなたに赤い旗であるべき問題「を解決するための最も適切なツールを使用していない」のこのようなものを。あなたのリソースは、それが何であれ、不適切な方法で問題を解決するように教えています。実際のところ、なぜここでCでループを使用しないのですか?あるいは、もし作者が関数型プログラミングを教えたいのであれば、なぜ彼らはC以外の言語を使うだろうか? より良い本を手に入れよう!

それにもかかわらず、ここで私は自分自身が答えを提供して見つける...

まず第一に、は、彼らは両方ループ技術です!私はあなたがは、任意のループを使用することができないと述べているとき、あなたが実際に手続きループ(すなわちループがgotowhiledo...whileまたはforから構築された)、および構築されていない機能ループ(を参照している収集します再帰関数アプリケーションによって)。それらは両方とも技術的にはループであり、Cは手続き型言語であるため、手順ループを使用する必要があります。それにもかかわらず...

パターンがあります!手続きループは、パターンを観察して再現するだけで、機能ループに変換することができます。つまり、すべての手続きループには同等の機能ループがあり、それらはすべて非常に似通っています。下のパターンを探します。ここで

は基本手続きループ含む関数です:

void procedural_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) { 
    while (source[source_position] != '\0') { 
     source_position++; 
    } 
} 

を...と、ここでは、機能ループの通りです:

void functional_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) { 
    if (source[source_position] != '\0') { 
     source_position++; 
     functional_loop_on_str(source, source_position, dest, dest_position); 
    } 
} 

コードの2枚が非常に似ているようです、彼らはいないの?どのような手順ループも、この観察に基づいて機能的に等価なものに簡単に変換できます。ループ内に埋め込まれた余分なコードを追加するだけです。練習として、このコードの同一部分を分離することを検討してください。彼らは一般に両方のコードで同じ場所に座っています。彼らは見つけるのが難しくありません!実際には、ここではそれらの違い、サイド・バイ・サイドです:

while ...         if ... 
                functional_loop_on_str... 

が唯一の問題は、この質問には無関係である、バックトラック時には必要である場所に来ます。したがって、手続き型バージョンをと書いて、機能バージョンに簡単に変換できるはずです。

void procedural_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) { 
    while (source[source_position] != '\0') { 
     int value, nbytes, success = sscanf(source + source_position, "%d%n", &value, &nbytes); 
     if (!success) { nbytes = 1; } 
     else { /* XXX: You do this part! 
       *  You need to do something with value, dest and dest_position */ 
     } 
     source_position += nbytes; 
    } 
} 

を...と、ここでは、パターンを再現ことにより、私たちの機能バージョンに翻訳されています:私はあなたを始めることを許可

void functional_loop_on_str(char const *source, size_t source_position, int *dest, size_t dest_position) { 
    if (source[source_position] != '\0') { 
     int value, nbytes, success = sscanf(source + source_position, "%d%n", &value, &nbytes); 
     if (!success) { nbytes = 1; } 
     else { /* XXX: You do this part! 
       *  You need to do something with value, dest and dest_position */ 
     } 
     source_position += nbytes; 
     functional_loop_on_str(source, source_position, dest, dest_position) 
    } 
} 

実際の間でどのように変化したかを少しお知らせ2つの例。パターンのほとんどはまだそこにある!上記の練習を思い出してください。さて、ここで同じことをして、手続き型から機能型への変換時に同じ場所で同じ変更が行われることを知ることができます。

このパターンは、関数型プログラミングとCプログラミングに関する(より良い)本についての(より良い)本を読んだり、パターンを観察するためにこれらの基本的な例を自分で作成したことで分かりました。それにもかかわらず、私は私の信念に立つこと:

  1. あなた機能ループCでまたはそのことについては、手続き型言語が、特にない Cを使用すべきではありません。 Cが毎日の機能ループのために設計されていれば、標準で最適化が保証されます。ガイドがそうでない場合は、C Kernighan & Richieの祖先(第2版を選んでください)を作成した、巨大な青色の「C」の本のような新しいガイドを選択することを検討してください。私はそれを見つけるためにあなたを残します。
  2. 手続き型言語を使用しての機能要素を学習しないでください。これは思いがけないものです。スキームを検討する。 Schemeについて本当に素晴らしい "ウィザードブック"があります!

いずれにしても、の本が必要です。

+0

* * Upvoted **しかし、愚かな再帰の例があるからといって「もっと良い本を手に入れる」と言うのはやや難しいと思います。再帰を導入する場合、最初の例は常に意味がありません。 – Persixty

+0

@適切な環境で再帰を十分に研究していない人にとっては、あまりにも複雑な再帰の候補はあまりにも複雑な最初のステップです。どんなに*複雑ではないにせよ*すべての*候補者のために、*そして*私に来て話してください。 – Sebivor

+0

@Persixty再帰は複雑なトピックではありません。したがって、私は、OPが再帰に関するよりよい本、あるいはCに関するより良い本を必要としているという私の信念によって立っています。おそらく両方、おそらく後者です。 – Sebivor

関連する問題