こんにちは 目黒@C++学習中です

CComBSTR型の文字列の編集方法について教えて下さい。

既に代入済みのCComBSTR型の文字列を短くする方法がわかりません
以下はテストソースです。

sName = sName.m_str;の行を入れれば取あえず可能ですが
BoundsCheckerでエラーになります。
m_strをfreeしている為。

#スペースがトリムされてしまう、
#トリムを防ぐ方法があったら教えて下さい

#define UNICODE
#define _UNICODE
#include <windows.h>
#include <atlbase.h>
int main(void)
{
CComBSTR sName;

sName = L"012345789\\abc";
long lSize = sName.Length();
WCHAR* sP = ::StrRChr(sName,NULL,L'\\');
if (sP != NULL) {
*sP = 0;
lSize = sName.Length();
// sName = sName.m_str;
}
sName += L"efg";
return EXIT_SUCCESS;
}

このQ&Aに関連する最新のQ&A

C++ 学習」に関するQ&A: C言語の学習について

A 回答 (1件)

CComBSTRは直接編集はできないと思っています。



テストソースでは最終的にsNameが012345789efgになるようにしたいと言うことですよね。たとえば、sName = L"00\\efg"なら結果は"00efg"を期待しているのですね。
BSTRはNULLを突っ込んでも長さは変わりませんよね。
ちょっと助長かもしれませんが、もう一つCComBstrを使って結果を作成するのはいかがでしょうか?
if (sP != NULL) {
 WORD size = sP - sName.m_str;
 CComBSTR Tmp(size,sName);
 sName.Empty();
 sName = Tmp;
 lSize = sName.Length();
}
sName += L"efg";
return EXIT_SUCCESS;
    • good
    • 1
この回答へのお礼

回答ありがとう

ポインターの演算を避けたいので
下記のようにしました

if (sP != NULL) {
*sP = 0;
CComBSTR sWork = sDirName.m_str;
sDirName = sWork;
}

お礼日時:2001/04/23 12:59

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Qchar *str; と char* str;

char *str; と char* str;
どっちも同じことを意味しているんですか?

Aベストアンサー

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染むのでしょう。ちなみにそういう風な人たちは

char *str1, *str2;

とは、書けない体になっています。

char* str1;
char* str2;


変数の宣言だと、C に慣れていれば、char* str というのはちょっと違和感があるのは
私も分かりますが、関数のプロトタイプ宣言だと、どちらの方がすっきりしますか?

extern char *memcpy(char *, const char *);

extern char* memcpy(char*, const char*);


# まあ、どっちが正しい、っていうんじゃ無いんですよね

同じことを指している、というのは、先の回答の通りです。

また、ひとつの宣言で変数を複数宣言したときに、char* str という表記は間違い
易いじゃないか、ということが言われているのも事実です。実際、いろいろな C のソースを
見ていても、まずアスタリスクを型につけて書くのは、まずお目にかかれません。

ただ C++ では、char* str という宣言も良く使われています。

C++ に限らずオブジェクト指向の言語は、強く型を意識するので、「文字のポインタ型」と
いう意味で、まとめて書く方が馴染む...続きを読む

Q#define NULL ((void *)0) の弊害

よく話題にされるヌルポインタについての疑問です。

定数の0は、それがポインタと解されるべき文脈では
ヌルポインタに読み替えられますが、
可変長引数のようにポインタであることがコンパイラには判断できない文脈では、
明示的にキャストしてやらなければなりません。
このとき、#define NULL 0 と定義されている処理系では、
NULLを使っても定数の0を書いたのと全く同じであり、
上のような場合におけるキャストの必要性からは逃れられません。
しかし、たまたま自分の処理系で
#define NULL ((void *)0) と定義されていれば、
キャストを行わなくてもNULLを使うことによって正しく動いてしまいます。
ということは、#define NULL ((void *)0) と定義された処理系しか
使ったことの無いプログラマは、
「NULLを使うこと自体が、これはポインタだよという意志表示になる」
と錯覚してしまう危険性をはらんでいることになります。
この人の書いた「NULLを使い、必要なキャストを省略しているソース」を、
#define NULL 0 と定義された処理系でコンパイルすると
正しく動作しない可能性があります。

こういう弊害があるにもかかわらず、
ANSI Cでは #define NULL 0 のほかに
#define NULL ((void *)0) も許しているのは、
一体なぜなのでしょうか。
メリットもあるのでしょうか?

よく話題にされるヌルポインタについての疑問です。

定数の0は、それがポインタと解されるべき文脈では
ヌルポインタに読み替えられますが、
可変長引数のようにポインタであることがコンパイラには判断できない文脈では、
明示的にキャストしてやらなければなりません。
このとき、#define NULL 0 と定義されている処理系では、
NULLを使っても定数の0を書いたのと全く同じであり、
上のような場合におけるキャストの必要性からは逃れられません。
しかし、たまたま自分の処理系で
#define NULL ((voi...続きを読む

Aベストアンサー

(1)
> ポインタと数値との内部構造の共通性から
> 結果として正しく動く、という意味でよろしいでしょうか?
その解釈でよいと思います。
私は「NULLは0または0Lと同一構造をもつ無効ポインタ」という解釈で使っています。

(2)
> すなわちNULLをキャスト無しで用いて大丈夫な場合が無くなってしまうのでしょうか?
例えばintel16bit系ではコンパイラが「デフォルトポインタ構造」を提供します。
メモリモデルと呼ばれるもので、コンパイルオプションによって16bitポインタと32bitポインタが指定可能です。
デフォルトポインタ構造を持つ無効ポインタをNULLと表現することは可能になります。
しかし、コンパイルオプションで16bitポインタを指定している場合でも、32bitポインタが必要なことがあり、この場合は適切なキャストが必要です。
他の処理系でも同様な措置によって「多くの場合はNULLが利用可能」と言うことになるでしょう。
しかし、「デフォルトのポインタ構造が可変」という状況はポータビリティーを阻害する可能性があることは間違いありません。

(1)
> ポインタと数値との内部構造の共通性から
> 結果として正しく動く、という意味でよろしいでしょうか?
その解釈でよいと思います。
私は「NULLは0または0Lと同一構造をもつ無効ポインタ」という解釈で使っています。

(2)
> すなわちNULLをキャスト無しで用いて大丈夫な場合が無くなってしまうのでしょうか?
例えばintel16bit系ではコンパイラが「デフォルトポインタ構造」を提供します。
メモリモデルと呼ばれるもので、コンパイルオプションによって16bitポインタと32bitポインタが指定可能で...続きを読む

QC言語のプログラムで#includeを使わず#includeだけで

C言語のプログラムで#include<math.h>を使わず#include<stdio.h>だけで√(sqrt)を表現することは可能でしょうか?

Aベストアンサー

ご自分で sqrt 関数を作れば可能です。
こんな感じでしょうか。

#include <stdio.h>

static double
sqrt (double s)
{
 double x = s / 2.0;
 double last_x = 0.0;

 while (x != last_x)
 {
  last_x = x;
  x = (x + s / x) / 2.0;
 }

 return (x);
}

int
main (int argc, char * argv[])
{
 printf ("sqrt (%f) = %f\n", 3.0, sqrt (3.0));
}

Q【#define】 defineで定義した値を配列のサイズに使う事は可能?

タイトルの通り、defineで定義した値を配列のサイズ指定に使いたいと考えています。
この場合、次のような使い方をしても問題ないのでしょうか?

/* サンプルここから */
#define SIZE_A 10
#define SIZE_B 20
#define SIZE_ALL (SIZE_A * SIZE_B)

cahr ARR[SIZE_ALL];
/* サンプルここまで */

コンパイル時にワーニング等はありませんが、int型という型を宣言していないSIZE_ALLを要素数として使用するのが不安に感じるのですが問題ないのでしょうか?

int SIZE_int = SIZE_ALL;
とdefineした値を明示的にint型変数に代入した上で、
cahr ARR[SIZE_int];
とすべきなのでしょうか?

初歩的な質問ですが、ご教示お願いします。

Aベストアンサー

★特に問題ありません。
・普通に define された定数を掛け算などして新しい記号定数を定義します。
 そしてその記号定数を配列などの添え字に使います。
 そもそも define された定数は通常は int 型と同じになります。
 #define SIZE_A 10…int型
 #define SIZE_A 10L…long型
 #define SIZE_A 10LL…long long型
 となります。
 『L』や『LL』のサフィックスを付けないとすべて int 型に解釈されます。
 つまり、プリプロセッサ命令は単純な文字列の置換ですのでサフィックスを
 付けないと int 型になるわけですよ。
・もし char 型にしたいならキャストを指定します。
 例えば
 #define SIZE_A ((char)(10))
 とします。
・もう既に回答がありますが
>int SIZE_int = SIZE_ALL;
>とdefineした値を明示的にint型変数に代入した上で、
>cahr ARR[SIZE_int];
>とすべきなのでしょうか?
 ↑
 この方法は新しい記述方法です。
 1999年の最新のC言語の規格です。
 この C99 にすべてのコンパイラが対応しているわけではないため使わない方が
 良いかもしれません。この記述が利用できれば便利なこともありますが…。
・最後にカッコをつけた方が良いですよ。
 #define SIZE_A (10)
 #define SIZE_B (20)
 #define SIZE_ALL (SIZE_A * SIZE_B)
 という風に SIZE_A、SIZE_B に括弧を付けます。
 これは今後 SIZE_A を『10 + 20』と定義した際に括弧がないと計算式が
 正しくなくなるので付けるように習慣を付けておいた方が良いということです。
 つまり今後
 #define SIZE_A 10 + 20
 #define SIZE_B 20 * 3
 #define SIZE_ALL (SIZE_A * SIZE_B)
 と定義したとします。
 すると SIZE_ALL は (10 + 20 * 20 * 3) と置換されますが計算式が掛け算を先に
 する数学上のルールより意図しない結果になります。正しくは SIZE_ALL=1800 に
 なるべくところが SIZE_ALL=1210 となってしまいます。
・これを防ぐには2つ。
 #define SIZE_A (10 + 20)
 #define SIZE_B (20 * 3)
 #define SIZE_ALL (SIZE_A * SIZE_B)
 もしくは
 #define SIZE_A 10 + 20
 #define SIZE_B 20 * 3
 #define SIZE_ALL ((SIZE_A) * (SIZE_B))
 と定義します。
 どちらにカッコを付けても同じですが私はすべてにカッコを付ける派です。
・参考にして下さい。

★特に問題ありません。
・普通に define された定数を掛け算などして新しい記号定数を定義します。
 そしてその記号定数を配列などの添え字に使います。
 そもそも define された定数は通常は int 型と同じになります。
 #define SIZE_A 10…int型
 #define SIZE_A 10L…long型
 #define SIZE_A 10LL…long long型
 となります。
 『L』や『LL』のサフィックスを付けないとすべて int 型に解釈されます。
 つまり、プリプロセッサ命令は単純な文字列の置換ですのでサフィックスを
 付けないと ...続きを読む

Q#include "_cv.h"の設定を教えて

VisualStudioC++2010を用いて、#include "_cv.h"を使用したいのですが、ファイルが存在する場所
「C:\Program Files\OpenCV\cv\src」を追加のインクルードファイルに入れても以下のエラーがでます。
1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error C2146: 構文エラー : ';' が、識別子 'icvDepthToDataType' の前に必要です。
1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error C2433: 'CvDataType' : 'inline' はデータ宣言をするのに使用できません。
1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
・・・・・

どなたか#include "_cv.h"の設定の仕方を教えてくれないでしょうか?

VisualStudioC++2010を用いて、#include "_cv.h"を使用したいのですが、ファイルが存在する場所
「C:\Program Files\OpenCV\cv\src」を追加のインクルードファイルに入れても以下のエラーがでます。
1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error C2146: 構文エラー : ';' が、識別子 'icvDepthToDataType' の前に必要です。
1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error C2433: 'CvDataType' : 'inline' はデータ宣言をするのに使用できません。
1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error...続きを読む

Aベストアンサー

何をコンパイルしようとしているのですか?

srcの下にあるのファイルだったら、OpenCVをソースからビルドするときに使うファイルだと思われます。

(コンパイル済みのライブラリを使うだけの)一般の利用者が直接_cv.hを使う必要は無いはずです。
あなたの作ったプログラムに#include "_cv.h"とあるなら、それが間違いです。


OpenCV自体のビルドなら、サイト等にビルドのしかたが書いてあります。
includeパスなども自動で設定されるし、オプション等も正しく設定されるので、よほどのことが無いかぎりエラーにはなりません。
失敗するのは、やるべき過程をやっていないのが原因と思われます。



> 1>C:\Program Files\OpenCV\cv\src\_cv.h(84): error C2146: 構文エラー : ';' が、識別子 'icvDepthToDataType' の前に必要です

このような感じでエラーが出ている、ということは、ファイルは見つかっている、ということで。そうでなければ「ファイルが見つからない」旨のエラーになりますから。

何をコンパイルしようとしているのですか?

srcの下にあるのファイルだったら、OpenCVをソースからビルドするときに使うファイルだと思われます。

(コンパイル済みのライブラリを使うだけの)一般の利用者が直接_cv.hを使う必要は無いはずです。
あなたの作ったプログラムに#include "_cv.h"とあるなら、それが間違いです。


OpenCV自体のビルドなら、サイト等にビルドのしかたが書いてあります。
includeパスなども自動で設定されるし、オプション等も正しく設定されるので、よほどのことが無いかぎりエラーには...続きを読む


人気Q&Aランキング

おすすめ情報