2017-05-07 4 views
0

プログラミングとC++にはあまり新しくないので、配列変換の手引き

配列の内容(ユーザーからの入力)をあらかじめ宣言されている略語に変換する割り当てに固執しています。

私はそれをstrcpy( "と"、 "+")と同じくらい簡単にします。 文字列内の単語 'and'を '+'記号に変更します。

残念ながら、どのように関数を構成しても問題ありません。推奨されていない変換警告(バリアントループと直接アプリケーションが試行されました)が表示されます。

サイドノート;これは割り当てベースなので、私の文字列のショートカットは厳しく制限されており、ポインタはありません(私はそれらを使ってフォルトをクリアするいくつかのバージョンを見てきました)。

私は宿題をする人を探していません。 depを作成せずにstrcpyを適用する方法に関するガイダンスだけです。警告。おそらく、私はstrcpyをまったく使用すべきではないでしょうか?

この場合でも、新しいVERYです。

ありがとうございました。

+4

あなたのコードはこれまで提供できますか?そして入力配列の例? – Mazaryk

+0

あなたはコピーではなく_replace_を記述します。 'String x ="これとそれ "; x.replace( "and"、 "+"); Serial.println(x); ' – dandavis

+1

これは純粋にプログラミングに関する質問であり、Arduinoの質問ではありません。 VTC。 –

答えて

2

strcpyは、2番目の文字列の内容を最初の文字列のメモリにコピーします。文字列リテラルを文字列リテラルにコピーするので、それを行うことはできません(文字列リテラルに書き込むことはできません)ので、不平を言います。

代わりに、独自の検索と置換システムを構築する必要があります。 strstr()を使用すると、文字列内の部分文字列を検索できます。見つかった場合は、その文字列の先頭にポインタを返します。

サンプルストリングJack and Jill went up the hillを考えてみましょう。それ0x104だろう(0x100 + 4)内の文字列(スペースを含む)(例えば0x100)を加えた単語のオフセット「と」の先頭のアドレスを返します

char *andloc = strstr(buffer, " and "); 

見つかった場合は、&シンボルに置き換えることができます。しかし、それは文字列を終了するので、strcpyを使用することはできません。代わりに、手動でバイトを設定するか、memcpyを使用することができます。

if (andloc != NULL) { // it's been found 
    andloc[1] = '&'; 
    andloc[2] = ' '; 
} 

か:

if (andloc != NULL) { // it's been found 
    memcpy(andloc, " & ", 3); 
} 

Jack & d Jill went up the hillことになります。私たちはまだそこにいません。次に、古い "and"から "d"をカバーするために、すべてをシャッフルする必要があります。そのためには、strcpyまたはmemcpyを使用できると思っていましたが、文字列(送信元と送信先)が重複し、両方のマニュアルページに文字列が重複してはならないと書かれていて、代わりにmemmoveを使用してください。

ですから、「&」の代わりにした後に「D」の後に文字列の内容を移動することができます。

memmove(andloc + 3, andloc + 5, strlen(andloc + 5) + 1); 

はそのような文字列に番号を追加するには、ポインタのアドレスに追加します。そこで古い "and"の文字列の5文字からさらに古い "and"位置の先頭から3文字で始まるスペースにデータをコピーします。コピーする量は、文字列の終わりにNULL文字をコピーするように、 "and"位置の先頭に5文字を加えた文字列の長さ+ 1です。それをやっての

別のマニュアルの方法は、あなたが文字列の終わりを見つけるまで、各文字を反復処理するために、次のようになります。

char *to = andloc + 3; 
char *from = andloc + 5; 
while (*from) { // Until the end of the string 
    *to = *from; // Copy one character 
    to++;  // Move to the ... 
    from++;  // ... next character pair 
} 
*to = 0; // Add the end of string marker. 

は、だから今のいずれかの方法は、文字列のメモリが含まれています

Jack & Jill went up the hill\0l\0 

\0は文字列マーカーの末尾なので、実際の文字列 "content"は最初の\0までとなり、l\0は無視されます。

これは、小さなもので部品を交換する場合にのみ有効です。文字列のサイズが大きくなるような大きさに置き換える場合は、コンテンツをスクラッチパッドに最初にコピーし、完成した文字列を格納するのに十分な空き領域があることを確認してください(これはmemmoveです。種類のものは、しばしばセキュリティ上の頭痛であり、ハッキングされるシステムの最大の原因の1つである「バッファオーバーラン」の大きな原因です。また、全体を逆方向に行う必要があります。最初に文字列の後半部分を移動して部屋を作り、次に2つの半分の間のギャップを修正します。

+0

ガイダンスをありがとうございますが、これは依然として割り当てパラメータを超えていました。私は許可されたものと一緒に働きました...そして、それは私がたくさん進歩するのを助けました。ありがとうございました。 これまでの変換プロトタイプを示します( "And"から "+"へ)。それは私にアウトプットを与えているわけではなく、次のステップが不明です。私が取るべき更新のステップがあるかどうか、もしそうなら、私はそれがどのように見えるか確信しています。 –

+0

割り当てパラメータは正確には何ですか? – Majenko

+0

char変換() { \t char文[SIZE]; char nsentence [SIZE]; int i; \t int senti = 0; \t int nsenti = 0; \t bool same = true; \t行う\t { \t \t場合(文[senti] == '|文[senti] == '') \t \t \t真=同じ。 \t \t他の場合(文[senti + 1] = 'N' |文[senti + 1] = 'n' の!)//のtoupper \t \t \t偽=同じ。 \t \t if(senti [senti + 2]!= 'D' |文[senti + 2]!= 'd') \t \t \t同じ= false; \t \t \t場合(同じ) \t \t \t { \t \t \t \t同じ= "+"。 \t \t \t \t { \t \t \t \t \t nsentence [nsenti + I] =文[senti + I](; iがstrlenを( "AND")を