問題タブ [char-pointer]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 文字列を文字ポインタに変換しようとしていますか?
私は太陽の下ですべてを試して、簡単な次のことを行いました:
1) stdin から入力文字列を受け取ります。
2) それを char ポインターに変換して、表/回文検索関数に渡すことができるようにします。
ステップ 2 の後半は自信がありますが、ハッキングできない型の一致です。以下は、問題の私の本体です。palin 関数のプロトタイプは ですint palin(char *str)
。
何か案は?c_str()
定数ポインタ char が必要なため、変換でも問題が発生しますが、char ポインタは変更されます。
c++ - スイッチケースの使用エラー
次のコードで:
は char ポインターであり、エラーは次のとおりです: エラー: 数量が整数ではありません...
c++ - std::string のベクトルを char*** にキャストします
char***
パラメータを必要とする API 関数があり、 vector<std::string>
. std::string
それをさせてくれるメンバー関数はありますか?
このようにして、最初の要素への char ポインターのみを取得します。
c++ - OpenGL 仕様に従って、(任意のプラットフォームで) char* 型が正しく実装されることを安全に保証するにはどうすればよいですか?
c++ と OpenGL3+ を使用したグラフィックス プログラミングに頭を悩ませようとしているときに、char 型、それへのポインター、および他の char ポインター型への潜在的な暗黙的または明示的な変換に関する、少し専門的な理解の問題に遭遇しました。解決策を見つけることができたと思いますが、これについてあなたの見解を求めて再確認したいと思います.
現在 (2014 年 10 月) のOpenGL4.5 コア プロファイル仕様(第 2.2 章のコマンド構文の表 2.2) には、OpenGL データ型がリストされ、明示的に記載されています。
GL 型は C 型ではありません。したがって、たとえば、GL 型 int は、このドキュメント以外では GLint と呼ばれ、必ずしも C 型 int と同等ではありません。実装では、表に示されている正確な数のビットを使用して GL 型を表す必要があります。
この表の GLchar 型は、文字列を構成する文字を表すために使用されるビット幅 8 の型として指定されています。
GLchar が提供するものをさらに絞り込むために、GLSL 仕様( OpenGL Shading Language 4.50、2014年 7 月、Chapter 3.1 Character Set and Phases of Compilation) を参照できます。
OpenGL シェーディング言語に使用されるソース文字セットは、UTF-8 エンコード方式の Unicode です。
今、私が探していた OpenGL ライブラリ ヘッダーでこれを実装する方法は簡単です。
もちろん、これは私が引用したばかりの「GL 型は C 型ではない」という声明に反するものです。
typedef は、基になる型が将来変更される可能性がある状況を想定しているため、通常、これは問題になりません。
問題はユーザー実装で始まります。
OpenGL に関するいくつかのチュートリアルを経て、GLSL ソース コードを処理に必要な GLchar 配列に割り当てるさまざまな方法に出会いました。(すべてのリンクを提供していないことをお許しください。現在、そうするために必要な評判がありません。)
サイト open.gl はこれを行うのが好きです:
またはこれ:
lazyfoo.net (Chapter 30 Loading Text File Shaders) では、ソース コードがファイルから変数に読み込まれ (私の好みの方法) std::string shaderString
、GL 文字列の初期化に使用されます。
私がこれまでに見た中で最も冒険的なアプローチは、シェーダー ファイルを Google でロードしたときに最初に得たものです。明示的なキャストを使用する OpenGL SDK でホストされているロードに関する ClockworkCoders チュートリアルではなく、GLchar*
次GLubyte*
のようにします。
まともな C++ コンパイラは、ここで無効な変換エラーを出します。g++ コンパイラは、-fpermissive フラグが設定されている場合にのみ、警告を出して実行します。そのようにコンパイルすると、最終的には と同じ長さの基本型のGLubyte
単なるtypedef
エイリアスであるため、コードは機能します。この場合、暗黙的なポインター変換によって警告が生成される可能性がありますが、それでも正しいことを行う必要があります。これは C++ 標準に反するため、 はorと互換性がないため、このようにするのは悪い習慣です。それは私が持っていた問題に私をもたらします: unsigned char
char
char*
signed
unsigned char*
私の要点は、これらのチュートリアルはすべて、OpenGL 仕様の実装が現在、基本的な型の typedef の形式での単なるウィンドウ ドレッシングであるという基本的な事実に依存しているということです。この仮定は、仕様ではまったくカバーされていません。さらに悪いことに、GL 型を C 型と見なすことは明らかに推奨されていません。
将来、何らかの理由で OpenGL の実装が変更され、それGLchar
が の単純なtypedef
エイリアスではなくなったchar
場合、互換性のない型へのポインタ間の暗黙的な変換が行われないため、このようなコードはコンパイルされなくなります。場合によっては、無効なポインター変換を無視するようにコンパイラーに指示することは確かに可能ですが、そのような不適切なプログラミングへのゲートを開くと、コードに他のあらゆる種類の問題が発生する可能性があります。
私の理解では、それを正しく行っている場所を 1 つだけ見たことがあります。シェーダー コンパイルに関する公式の opengl.org wiki の例です。
他のチュートリアルとの唯一の違いは、割り当て前の明示的なキャストです。const GLchar*
醜いことはわかっていますが、私が見る限り、OpenGL 仕様の有効な将来の実装に対してコードを安全にします (要約): UTF-8 エンコーディング スキームで文字を表すビット サイズ 8 のタイプ。
私の推論を説明するために、GLchar2
この仕様を満たす単純なクラスを作成しましたが、基本型への、または基本型からの暗黙的なポインター変換は許可されなくなりました。
クラスの記述に加えて、入力および出力ストリーム演算子のオーバーロードを実装して、クラスからの読み取りと書き込み、および c-string スタイルのヌル終了GLchar2
配列を正しく処理することに注意してください。char
これは、クラスの内部構造を知らなくても可能です。ただし、型とGLchar2
(それらのポインターではない)の間の暗黙的な変換を提供する場合に限ります。char
とGLchar2
またはそれらのポインター型の間で明示的な変換は必要ありません。
この の実装GLchar
が価値がある、または完全であると主張するつもりはありませんが、デモンストレーションの目的で行う必要があります。と比較するとtypedef char GLchar1;
、このタイプでできることとできないことがわかります。
GLchar
C++ 標準に違反することなく常に文字列を正しく処理するコードを作成するには、少なくとも 2 つの実行可能な方法があると結論付けています。
char 配列から配列への明示的な変換を使用します
GLchar
(乱雑ですが実行可能です)。const GLchar* sourceCode = (const GLchar*)"some code";
std::string sourceString = std::string("some code"); // can be from a file GLchar* sourceCode = (GLchar*) sourceString.c_str();
入力ストリーム演算子を使用して、文字列をファイルから配列に直接読み取ります
GLchar
。
2 番目の方法には、明示的な変換が必要ないという利点がありますが、それを実装するには、文字列用のスペースを動的に割り当てる必要があります。もう 1 つの潜在的な欠点は、OpenGL が入力および出力ストリーム演算子の型またはポインター型を処理するためのオーバーロードを必ずしも提供しないことです。ただし、既に示したように、これらのオーバーロードを自分で作成することは、少なくとも char との間の型変換が実装されている限り、魔法の問題ではありません。
これまでのところ、c-string とまったく同じ構文を提供する、ファイルからの入力に対する実行可能なオーバーロードは他に見つかりませんでした。
さて、私の質問は次のとおりです。私のコードが OpenGL によって行われる可能性のある変更に対して安全なままであるように、これを正しく考えましたか?答えが「はい」か「いいえ」かに関係なく、上位互換性を確保するためのより良い (つまり、より安全な) 方法はありますか?私のコードの?
また、このstackoverflowの質問と回答を読みましたが、私が知る限り、文字列は基本的な型ではないため、カバーしていません。
また、暗黙的なポインター変換を提供するクラスを作成する方法も尋ねていません (ただし、それは興味深い演習になります)。この例のクラスのポイントは、実装を変更することを決定した場合に OpenGL がそのようなものを提供するという保証がないため、暗黙的なポインター割り当てを禁止することです。
c - ユニット化されたヒープ割り当ての誤解 (コードは機能します -- Valgrind エラーを削除するには修正が必要です)
私のコードは正常に動作しますが、valgrind エラーが発生します。これらの malloc および free ステートメントを char * * dest で正しく使用することに関して、コードを修正する方法を知りたいです。間違った場所で実行していない限り、malloc と free を実行しないように言わないでください。answer03.c の strcat_ex の修正されたコード、または malloc 後の malloc、free、および初期化に関する私の誤解の説明のいずれかまたは両方を提供していただければ幸いです。長い投稿を前もってお詫びしますが、必要なものはすべて提供したかったのです。
詳細情報: 私は主にメソッド strcat_ex に焦点を当てています (これは strncat と同じではありません。関数の説明を読んで int *n との違いを確認してください)。この問題は、文字列 (char *) のパラメーター メモリを dest (char **) に再割り当てする必要があり、割り当てられた十分なスペースがなく、malloc した後に初期化されないという事実で発生します。これは、malloc の後で「ヒープ」メモリを初期化する方法がわかりません。malloc の後に初期化を行う必要があるとは思いませんでした。
注: pa03.c と answer03.h はまったく変更しないでください。
関連する valgrind エラー ( memcheck.log ) は次のとおりです。
参照された行:
16 行目 ( pa03.cから) は変更しないでください。メソッド パラメーターdef、n、src、および戻り変数 resultの呼び出しの例として、以下のpa03.cで宣言されています。
21 行目 ( answer03.cから):
29 行目 ( answer03.cから):
関連するソースコードは次のとおりです。ここで valgrind エラーが発生し、stackoverflow に関する知識が必要になります (
answer03.c ) :
これらの凶悪な間違いをお詫びしますが、将来の読者が理解できるように行を残しました。
この点より下のすべては変更されないままであり、正しいことが知られています:
私のコンパイル文(Makefile):
私の valgrind ステートメント ( Makefile ):
strcat_ex ( answer03.h )の関数定義は次のとおりです。
source をテストとして呼び出す関連コード ( pa03.c ) は次のとおりです。
関連する出力は次のとおりです ( pa03.cからの印刷ステートメント): これは正しい出力です (現在のコードで生成できる)。
最後の言葉:
このコードをコンパイルするために必要なファイルと、gcc と valgrind を使用した Linux の valgrind エラー ログを添付しました。valgrind には他にもありますが、最も関連性が高いと思われるものを投稿しました。前もって感謝します。
すべてのファイルを含む zip:
http://www.filedropper.com/files_11
c - int からの Basic C キャスト警告ポインタ
この警告/エラーを修正する方法を教えてください。「-」かどうかを判断するために、文字列の最初の文字だけを取得しようとしています。
エラー:
警告/エラーのあるソース:
15行目:
29 行目:
完全なソース: