0

変換で困っています。このプログラムでは文字列を使用できないため、を使用する必要がcharあります - エラーが発生します:

error C2664: 'printText' : cannot convert parameter 1 from 'const char [21]' to 'char'
1>          There is no context in which this conversion is possible

私はそれをconstポインタに変換しようとしました:

void printText(const char* text[100] = "notextgiven"...

しかし、それは役に立たないようで、何よりも多くのエラーが発生します。

私のプログラム:

#include <iostream>
using namespace std;

void printText(char, char, int);

int main(){
    printText("I hear and I forget.", "*", 15);
}

void printText(char text[100] = "notextgiven", char symbol = ' ', int repeat = 10){
    int temp = 0;
    while(temp < repeat){
        cout << symbol;
            temp++;
    }

    cout << text;

    temp = 0;
    while(temp < repeat){
        cout << symbol << endl;
            temp++
    }
}
4

4 に答える 4

5

これは、実行しようとしている関数を定義する正しい方法ではありません

void printText(char text[100] = "notextgiven", char symbol = ' ', int repeat = 10)

代わりにこれを試してください

void printText(const char* text, char symbol, int repeat)

これにより、プログラムをコンパイルできるようになります。この行も変更します

 printText("I hear and I forget.", "*", 15);

printText("I hear and I forget.", '*', 15);
                                  ^ ^ 

一重引用符は単一の char 変数に使用され、二重引用符はそれを文字列リテラルとして扱います。これは宿題なので、具体的に使用するように求められたかもしれませんがchar*、一般的に C++ を使用しているため、使用する方がはるかに優れています。std::string

于 2012-08-25T22:21:29.790 に答える
2

元の関数では、最初に文字列全体を単一の文字に入れようとしましたが、これは明らかに不可能です。次に、合理的な解決策を試みましたが、主に歴史的な理由で C++ では許可されていません。

に変更printTextします

void printText(const char *, char, int);

なぜこれが必要なのですか?

  • C 文字列はchars の配列です。
  • C/C++ では配列を値で渡すことはできません (特に理由はありません1 )。
  • 配列の名前は、その最初の要素へのポインターに減衰します。最初の要素へのポインターがある場合は、配列全体にインデックスを付けることができます。

このため、C/C++ 関数に配列を渡すときは、実際には最初の要素へのポインターを渡します。ジェネリック配列の場合は、別のパラメーターで配列のサイズも渡します (そうしないと、呼び出された関数は配列の調査を停止するタイミングを認識できません)。C 文字列の場合は、慣例により、最初の '\ で終わるため、必要ありません。 0' 文字 (ヌル ターミネータ)。

なぜconstですか?関数は渡される文字列を変更する必要がないため、この事実を明確にし、呼び出しconst元がコンパイルエラーを発生させることなく文字列を渡すことを許可します (理論上の文字列リテラルはconst変更できないため、文字列です。ただし、char *歴史的な理由により、暗黙的に再度変換される可能性があります)。


ところで、サイズ指定された配列パラメーターを関数に宣言することは本質的に禁止されているわけではありませんが、前述の互換性の問題のために、とにかくポインターとして解釈されます。関数の定義ではなく宣言(=prototype) で指定する必要があるため、デフォルト値でエラーが発生します。


最後に、他の人が気づいたように、関数呼び出しで

printText("I hear and I forget.", "*", 15);

2 番目のパラメーターは文字列 (二重引用符で囲んだため) ですが、単純なchar(一重引用符で囲んだ) 必要があります。


  1. IIRCは、BやBCPLなどとの互換性と関係があります。ポイントは、配列を値で渡すことができない本質的な理由がないということです。
于 2012-08-25T22:20:02.653 に答える
1

関数に文字列を渡そうとしましたが、設定方法によれば、1 文字しか受け入れません。

printTextchar*代わりにchar(つまり、単一の文字ではなく一連の文字として)パラメータを取る必要があります。

したがって、代わりにprintText(char, char, int);前方宣言を にする必要がありますprintText(char*, char*, int)

同様に、関数のシグネチャは次のようになります。

void printText(char* text = "notextgiven", char* symbol = " ", int repeat = 10)

于 2012-08-25T22:22:02.140 に答える
0

元のタイトルで説明したエラー メッセージは、実際のエラー メッセージと完全に同じではないことに注意してください。(私はこれを自由に変更しました。) 最後の "[21]" は非常に重要です。特に、「[]」記号は配列を表します。したがって、コンパイラは、文字の配列から単一の文字に変換しようとしていることを伝えています。配列は複数の文字を保持できるため、コンパイラがこれを行うことができないと不平を言う理由は明らかです。

その説明が邪魔にならないので、コードを修正する方法を見てみましょう。コードで問題を引き起こしている 3 つの行があります。

関数宣言:

void printText(char, char, int); 

関数呼び出し:

printText("I hear and I forget.", "*", 15); 

関数定義:

void printText(char text[100] = "notextgiven", char symbol = ' ', int repeat = 10){ 
   //...
}

これらは、独自の関数を作成するための 3 つの要素であり、すべて一致する必要があります。そうでない場合、コンパイラは文句を言います。それでは、これらの各部分を分析してみましょう。最初の宣言:

void printText(char, char, int); 

ここでは、3 つの入力 (2 つの文字と 1 つの整数) を想定し、出力 ("void") を持たない "printText" という名前の関数を宣言します。

次に、関数定義を見てください。

void printText(char text[100] = "notextgiven", char symbol = ' ', int repeat = 10){ 
   //...
}

これは、3 つの入力と出力のない "printText" という名前の関数を定義します。ただし、よく見てください。この「printText」関数は、入力として文字配列、文字、および整数を必要とします。この入力のリストは宣言のリストとは異なるため、実際には宣言されたものとは完全に異なる関数です。

ここで、関数定義は関数が実際に何をするかを定義することにも言及したいと思います。これは「{」と「}」の間のコードです。一方、関数宣言は単に関数がどこかに存在することを示しますが、関数の内部で何が起こるかは示しません。コンパイラを満足させるには、両方が必要です。(技術的にはリンカーも関係しますが、その詳細は現在の質問にとって重要ではありません。)

もう 1 つ: あなたの関数は "=" でデフォルトの引数を提供します。これはあなたが意図したものではないと思います。あなたは始めたばかりなので、物事を複雑にするだけなので、これらを削除することを強くお勧めします. 関数に慣れてきたら、デフォルト引数について学ぶことができます。

最後に、関数呼び出しを見てみましょう。

printText("I hear and I forget.", "*", 15); 

この行は main() 関数に表示されるため、printText() 関数にその処理を実行するよう指示します。この行は、printText() 関数への入力も提供します。ここで与えられた入力は、2 つの文字列 (または文字配列) と整数であることに注意してください。(二重引用符で囲まれたもの -- "" -- は文字列であり、文字配列と同等です。) これは関数宣言によって記述された入力のリストと一致しないため、コンパイラは変換を試みます。リストされたタイプへの入力。それができないので、コンパイラは不平を言います。

あなたは実際に 3 番目の引数を に変更したいと考えています'*'。一重引用符に注意してください。これは、C++ (および他のほとんどのプログラミング言語) で単一の文字を示す方法です。

この説明が、コードで何が起こっているのかを理解するのに役立つことを願っています. C++ の学習を頑張ってください!

于 2012-08-25T22:50:06.877 に答える