【初心者歓迎】C/C++室 Ver.49【環境依存OK】at TECH
【初心者歓迎】C/C++室 Ver.49【環境依存OK】 - 暇つぶし2ch127:デフォルトの名無しさん
08/02/22 00:06:12
C#では見事に禁止だな

128:デフォルトの名無しさん
08/02/22 00:07:40
>>125
文法的に間違いではないが、お前の期待する動作はしないと思う

(1||2||3||4||5)は常に真となり、それとiの値が等しいかどうか
だよ?これ

129:デフォルトの名無しさん
08/02/22 00:08:18
>>125
ifの方も意図しているであろう動作はしない。
ただしコンパイルは通る。警告くらい出してくれるかも知れんが・・・

130:デフォルトの名無しさん
08/02/22 00:11:14
ありがとうございます。自分でもためしてみたけど無理だった
コンパイル通ってたから上手く動いてると思ってそのままつかってたよ…

131:デフォルトの名無しさん
08/02/22 00:19:40
>>127
C#も124みたいにcaseラベルを並べるのはありだと聞いた。

132:デフォルトの名無しさん
08/02/22 00:22:16
並べさせるくらいなら、コンマ区切りで書かせてくれてもいいのにね。

133:デフォルトの名無しさん
08/02/22 00:27:11
クラスの定義と代入を同時にやるにはどうやればいいですか?
int a=10; のようにです

134:デフォルトの名無しさん
08/02/22 00:28:19
「代入」 は既に宣言されている変数に対して行う操作なので
同時に出来る訳が無い。
初期化なら別だが。

135:デフォルトの名無しさん
08/02/22 00:30:45
operator を使おう

136:デフォルトの名無しさん
08/02/22 00:30:52
事故解決しました

137:デフォルトの名無しさん
08/02/22 00:32:34
これでできました

int main() {

class Test{
int x;
public:
Test (int y) {x=y;}
print(){ cout<<x<<endl; } };

Test a=10;
a.print();
return 0;
}

138:デフォルトの名無しさん
08/02/22 00:35:31
Test a=10;
a.print();
a=20;
a.print();

もできるんですね C++はすごいですね

139:デフォルトの名無しさん
08/02/22 00:37:27
往々にして望まない機能だけどな。
基本的に引数1つのコンストラクタには explicit つけとけ。

140:デフォルトの名無しさん
08/02/22 00:42:12
それよりも、構造体って感じの型でないクラスなのに
コピーコンストラクタとoperator =をコンパイラ任せにしているのが嫌だね。

141:デフォルトの名無しさん
08/02/22 00:43:15
コンパイラ任せに出来る時は
コンパイラ任せでいいよ。

142:デフォルトの名無しさん
08/02/22 00:48:46
138じゃないですが、

>>139
なんでですか?
(本当に理由を知りたいです。)


143:デフォルトの名無しさん
08/02/22 00:59:34
#include <iostream>
#include <vector>

class Vector {
public:
 Vector(size_t size) : m_array(size) { }
 void output() const {
  for(std::vector<int>::const_iterator it = m_array.begin();
     it != m_array.end(); ++it)
  {
   std::cout << *it << ' ';
  }
  std::cout << std::endl;
 }
private:
 std::vector<int> m_array;
};

void Foo(const Vector& v) {
 v.output();
}

int main() {
 Foo(5);   ←←←←←←←
}

これが直感的な挙動ではないことは分かってもらえると思う。
でも、コンパイル通るし、正常に動く。

explicit つけるとこういう時にコンパイルエラーにできる。
それでも Foo(Vector(5)); なら可だが、これは問題ないと感じてくれると思う。

144:デフォルトの名無しさん
08/02/22 00:59:53
>>91
どんなバグがでるのですか?
呼び出し側なにか影響でうるのですか?

145:デフォルトの名無しさん
08/02/22 01:01:23
input を変更した後に、
input が変更されていない事を前提とした処理を書いてしまうかもしれない。
あるいは、そういう処理があるにも関わらず、
それより前の地点で input を変更してしまうかもしれない。

そうなっていないか注意して探すよりは、
引数をいじらない方が良い。

146:デフォルトの名無しさん
08/02/22 01:08:46
みんな仮引数にconstって使わないんだよね。

147:デフォルトの名無しさん
08/02/22 01:09:55
一時期付けてみたけど、
あんま意味ないと思ってやめた。

148:デフォルトの名無しさん
08/02/22 01:12:29
>>145
なるほど
別にいじること自体がやばいわけじゃなくて

いじると間違い起こす原因となる可能性があるわけですね
ありがとうございました

149:デフォルトの名無しさん
08/02/22 01:14:13
だって関数の定義では付けてもいいけど、宣言では付けたくないので、
コピペじゃ済まなくなる。

150:デフォルトの名無しさん
08/02/22 01:14:45
>>131
fall throughは禁止じゃなかったっけ
何かキーワードがあったと思う
情報が古いかもしれんが

151:デフォルトの名無しさん
08/02/22 01:19:06
>>150
caseが連続する場合のみOK。その他は禁止。スレ違い。

152:デフォルトの名無しさん
08/02/22 01:19:25
>>143
ありがとうございます。
explicitは、暗黙の変換を抑制する機能なのですね。
しかしなんか上の例のコードは、すごくC++書き慣れた人な感じがしました。


153:デフォルトの名無しさん
08/02/22 01:20:21
>>150
>>124のように空のcaseラベルを並べたときはフォールスルーできる。
URLリンク(msdn2.microsoft.com)
スレ違いすまん。

154:133
08/02/22 02:00:16
関数の引数にクラスを使いたいのですが、クラスの宣言と代入を同時にするにはどうやればいいですか
intのようにコンストラクタではできませんでした

test y = f( x );
のようにです fはクラスを返します intではないです

155:デフォルトの名無しさん
08/02/22 02:11:42
>>154
testというのがクラスなら、testにconst test&型の引数を1つ取るコピーコンストラクタを作るんだ。

156:デフォルトの名無しさん
08/02/22 02:14:25
サンクス

157:デフォルトの名無しさん
08/02/22 07:02:49
>>154
何度も言うが、それは代入じゃない。
初期化だ。
初期化の場合、= を使っていても
test y = f(x); は test y(f(x)); と同義。

158:デフォルトの名無しさん
08/02/22 07:24:55
まったくのプログラム初心者です。
はじめににインストールする言語?をどれにするかがわかりません。
どういう意味かというと

ボーランド、とかマイクロソフトのvisual studioとかどれにすればいいのかです。
有料とか無料とかいろいろありますね。
できたら将来有料ソフトを販売可能なものがいいです。

今考えているのはマイクロソフトのVC++を考えているのですが、
C++とVC++は違うとか
どっかで聞いたりもしたので
初心者にはちんぷんかんぷんでわかりません。

よろしくお願いします

159:デフォルトの名無しさん
08/02/22 07:30:50
C++ は言語名。
VC++ は C++ を使って開発を行うためのツールの名前。

160:デフォルトの名無しさん
08/02/22 08:05:40
>>159
ありがとうございます。

161:デフォルトの名無しさん
08/02/22 11:08:37
VC++ はMSがWindows用ソフトを開発するために拡張した言語ともいえる
VC++のコードはほかのものでは動かせないものが多い

162:デフォルトの名無しさん
08/02/22 11:42:07
URLリンク(www.xlsoft.com)
このソフトを使えばJavaでもネイティブアプリケーションが作れると書いてあるのですが、そんなうまい話があるんですか?
もし本当ならJavaのパフォーマンス面での不利がだいぶ改善されると思うのですが

163:デフォルトの名無しさん
08/02/22 11:45:45
ここはC/C++スレですが

164:デフォルトの名無しさん
08/02/22 11:57:29
システム構築売るならまだしもソフト売るのにJavaはないだろ。
VCにしとけ。

165:デフォルトの名無しさん
08/02/22 11:59:00
perl2exeみたいなやつでは? 実行環境を圧縮してexeに詰め込む
利点としてはランタイムとかの導入がいらないだけで

166:デフォルトの名無しさん
08/02/22 12:21:11
スレ違い。ここでやれ
gcjって使ってる人います?
スレリンク(tech板)l50

167:デフォルトの名無しさん
08/02/22 12:31:13
この直し方教えてください!

IEBrowser->Document.charset="shift_jis";

error C2039: 'charset' : '_com_ptr_t<class _com_IIID<struct IDispatch,&struct __s_GUID _GUID_****> >' のメンバではありません。

168:167
08/02/22 12:35:30
文字コードの変換をしたいのですが・・・
この様に定義してあります

SHDocVw::IWebBrowser2Ptr IEBrowser;
IEBrowser.CreateInstance( __uuidof( SHDocVw::InternetExplorer ) );

169:デフォルトの名無しさん
08/02/22 12:51:05
>>167
こうでは?
IEBrowser->Document->charset= L"shift_jis";

170:167
08/02/22 12:55:40
>>169

error C2039: 'charset' : 'IDispatch' のメンバではありません。

になりました・・・

171:167
08/02/22 13:05:44
文字コードの変更方法わかったら教えてもらいたいですけど
そこだけVBAスクリプトを呼び出す事にします

172:デフォルトの名無しさん
08/02/22 13:08:27
>>170
じゃあこれはどう?
SHDocVw::IHTMLDocument2Ptr document = IEBrowser->Document;
docment->charset = L"shift_jis";


173:167
08/02/22 13:13:13
だめでした

174:デフォルトの名無しさん
08/02/22 13:23:38
QueryInterface

175:デフォルトの名無しさん
08/02/22 13:33:26
適当に書いたらやっぱダメだったか、すまん。
#import <mshtml.tlb>した上で、MSHTML::IHTMLDocument2Ptrだ。

176:デフォルトの名無しさん
08/02/22 13:34:40
>>174
ナントカPtr(の実態_com_ptr_t<>)のコンストラクタや代入演算子の中でQueryIntefaceが行われている。

177:デフォルトの名無しさん
08/02/22 14:08:38
πの値は、自分で3.1415926535...とかって書くしかないでしょうか。
numeric_limits<int>::max()とか、そういう書き方はないですか?


178:デフォルトの名無しさん
08/02/22 14:13:43
#ifndef M_PI
# define M_PI 3.1415926535
#endif

179:デフォルトの名無しさん
08/02/22 14:30:07
math.hをインクルードしたらM_PIとしてdefineされてる。
計算して出したいなら4*atan(1.0);

180:デフォルトの名無しさん
08/02/22 14:32:27
標準ではないのが玉に瑕。

181:デフォルトの名無しさん
08/02/22 15:02:49
>>178-180
ありがとうございます。
#include <cmath>
としてたのですが、M_PIでコンパイル通りました。


182:デフォルトの名無しさん
08/02/22 15:58:04
C初心者です。
実数→整数変換ですが、

double dval;
char buf[80];
int ival;

dval = -19.99; /* -19.99~19.99 */
dval = dval * 100.0;

sprintf(buf,"%.0f",dval);
ival = atoi(buf);

printf( "%f %d %d\n",dval,ival,(int)dval);
/* printf( "%f %d %d\n",dval,ival,(int)ceil(dval)); */


ivalを求める場合、上記の方法が一番精度が良いのですが
これ以外に方法はありますでしょうか?
ceil() や floor() 使っても誤差が出てしまいます。


183:デフォルトの名無しさん
08/02/22 16:05:51
>sprintf(buf,"%.0f",dval);
それ四捨五入してるだけだぞ
そんなんでいいなら ival = floor(dval * 100 + 0.5) とでもやればいい

元々 -19.99 という値自体が誤差を持ってるから、これを無くすことは出来ない
printf("%.20f\n", -19.99); とかやってみればわかる

本当に誤差が嫌なら、浮動小数点を使わない、という方法しかない

184:182
08/02/22 16:12:26
>>183

早速のRESありがとう御座います。

>そんなんでいいなら ival = floor(dval * 100 + 0.5) とでもやればいい

了解です。これで行きたいと思います。
 どうもありがとう御座いました。

185:デフォルトの名無しさん
08/02/22 16:53:31
char []型の要素を破棄して動的確保できませんか? 消せなくてもいいので別のアドレスに確保できませんか?

f(char *ch){
delete ch;
ch=new char[10];
strcpy(ch,"ssssssss");
}

main(){
char *ce=new char[2];
f(ce); cout<<ce<<endl;

char ch[]="test";
f(ch); cout<<ch<<endl;
}

186:デフォルトの名無しさん
08/02/22 16:55:19
もしくは、char *型とchar []型を判別して、書き換えられないなら始めにエラーにするのでもいいです

187:デフォルトの名無しさん
08/02/22 16:59:46
>>185
ごめんfで何がしたいのか分からない。

まぁ俺の第六感で回答すると、ポインタのポインタ使えばいいんじゃね

188:デフォルトの名無しさん
08/02/22 17:05:10
char a[10];
をコード内で書き換えてたとえば100個まで使えるようにしたいんです
はじめのaは破棄できなくてもいいので、a[50]とかにアクセスできるようになりませんか

189:デフォルトの名無しさん
08/02/22 17:07:46
Stringクラスの使い方でも覚えるとか

190:デフォルトの名無しさん
08/02/22 17:08:43
>>188
設計が間違ってるよ
>>185 みたいにすると激しく管理が難しい事になる

191:デフォルトの名無しさん
08/02/22 17:12:10
ポインタで文字列のアドレスが渡されたら、それが[]なのか*なのか渡された側にはわかりません
どうしたらいいですか

192:デフォルトの名無しさん
08/02/22 17:14:17
配列サイズも渡す

193:デフォルトの名無しさん
08/02/22 17:17:53
閃いたw

初めから1000個くらい確保しとけばいいじゃん

194:デフォルトの名無しさん
08/02/22 17:21:28
無理か

main(){
char ch[]="test";

char *ce=new char[20];
strcpy(ce,"ssss");

ch=ce;  //ここでエラー

cout<<ch<<endl;
}

195:デフォルトの名無しさん
08/02/22 17:22:10
あほすぎ

196:デフォルトの名無しさん
08/02/22 17:29:05
>>191
呼び出し側で呼び出す関数を変える

>>194
なにがしたいの?

197:デフォルトの名無しさん
08/02/22 18:10:41
>>194
こうすれば?

main(){
char chx[]="test";
char *ch = chx;

char *ce=new char[20];
strcpy(ce,"ssss");

ch=ce;  //エラーなし

cout<<ch<<endl;
}

198:デフォルトの名無しさん
08/02/22 18:36:59
>>185
恐らく、引数でもらった文字列を元に新な文字列を返そうと考えてるんだろうけど、
そうしたいのなら、

char* func(const char* str)
{
 char* s = new char[ほにゃらら];
 ほげほげ

 return s;
}
とした方が良い。

そもそも
char ch[] = "test";
の ch は配列の先頭のアドレスを返す「定数」なんだから、newで確保した領域を割り当てられるわけないよ。


199:デフォルトの名無しさん
08/02/22 19:05:33
レスありがとうございます
同じような質問なんですが、*chが確保されていてもいなくても、deleteするにはどうすればいいですか?
確保していないと実行時にエラーになります

200:デフォルトの名無しさん
08/02/22 19:08:14
言ってる事がよく分からんが、こういうこと?

if( ch )delete ch;

201:デフォルトの名無しさん
08/02/22 19:15:06
まともに動くのはaだけなんです どれでも動くようになりますか?

f(char *ch){ delete ch; ch=new char[10]; strcpy(ch,"ssssssss"); }

main(){
char *a=new char[1]; f(a); cout<<a<<endl;
char *b=NULL; f(b); cout<<b<<endl;
// char *c; f(c); cout<<c<<endl;
}

202:デフォルトの名無しさん
08/02/22 19:16:31
>>200  ifを組み込んでも動作しませんでした

203:デフォルトの名無しさん
08/02/22 19:16:40
void f(char*& ch)

204:デフォルトの名無しさん
08/02/22 19:17:29
つーか、大人しく std::string 使え

205:デフォルトの名無しさん
08/02/22 19:18:15
>>201
fの中でchに代入してもmainの方はaもbもcも変わらないよ?

f(int x){
x = 2;
}
main() {
int a = 1;
f(a);
cout << a << endl; // 2ではなく1と表示される
}

↑これ解ってる?

206:デフォルトの名無しさん
08/02/22 19:19:04
>>203 それを組み込んだらbも動作しました! でもcが実行時にエラー出ます >>200も同時にやってもだめです

207:デフォルトの名無しさん
08/02/22 19:20:20
>>205 char* や配列は参照渡しだとききました

208:デフォルトの名無しさん
08/02/22 19:20:23
初期化してねえのに delete できるわけねえだろ

209:デフォルトの名無しさん
08/02/22 19:20:49
>>207
ポインタは値渡し。

210:デフォルトの名無しさん
08/02/22 19:21:59
>>209 わかりました >>208 初期化していないことを調べる方法ないですか

211:デフォルトの名無しさん
08/02/22 19:23:11
aは配列と見なされて参照渡しになってるんですね

212:デフォルトの名無しさん
08/02/22 19:25:03
用語の部分で思考停止してるな。
何が起こってるのか考えた事無いだろう。

213:デフォルトの名無しさん
08/02/22 19:25:43
>>210
初期化されてるポインタと、
初期化してないけど偶然たまたま同じ値が入ってるポインタを、
見分ける方法が物理的にあると思うか?

214:デフォルトの名無しさん
08/02/22 19:26:39
deleteした瞬間に落ちます tryも無理です

f(char*& ch){
try{ delete ch; }
catch(...){cerr << "例外を受け取りました。" << endl;}
ch=new char[10]; strcpy(ch,"ssssssss"); }

main(){
char *a=new char[1]; f(a); cout<<a<<endl;
char *b=NULL; f(b); cout<<b<<endl;
char *c; f(c); cout<<c<<endl;
}

215:デフォルトの名無しさん
08/02/22 19:31:57
>>214
いい方法を教えてあげよう
関数 f の前にこれを書くんだ

/* この関数に初期化してないポインタを渡してはいけません */

216:デフォルトの名無しさん
08/02/22 19:43:25
基礎からやり直せよ

217:デフォルトの名無しさん
08/02/22 19:45:15
>>214
だーかーらーnewで確保したメモリを指してるポインタと、未初期化のポインタを見分け
る方法なんて存在しないんだってば。
ポインタ使うときは初期化しろって何で言われてるのか考えたことあるか?


218:デフォルトの名無しさん
08/02/22 19:49:31
#define HOGE int

void f(HOGE x) { cout << '(' << x << ')' << endl; x = 42; }

int main() {
 HOGE a = 10; f(a); cout << '(' << a << ')' << endl;
 HOGE b = 0; f(b); cout << '(' << b << ')' << endl;
 HOGE c; f(c); cout << '(' << c << ')' << endl;
}

これの挙動は分かるか?


#define HOGE char*

void f(HOGE x) { cout << '(' << x << ')' << endl; x = "f"; }

int main() {
 HOGE a = "a"; f(a); cout << '(' << a << ')' << endl;
 HOGE b = NULL; f(b); cout << '(' << b << ')' << endl;
 HOGE c; f(c); cout << '(' << c << ')' << endl;
}

んで、これの挙動は分かるか?

219:デフォルトの名無しさん
08/02/22 20:17:15
質問ですが、stringの参照で値を受け取るとき
memcpy(str, ch,10000);
のようにできますか?

220:デフォルトの名無しさん
08/02/22 20:37:35
お願いだから str.assign(10000, ch); としてください。
頼みますから。

221:デフォルトの名無しさん
08/02/22 20:45:34
>>220
strがchar*の予感

222:デフォルトの名無しさん
08/02/22 21:09:01
凄く無駄なレス消費してんなw

223:デフォルトの名無しさん
08/02/22 21:15:15
昔ならともかく惜しむもんではないが無駄感は否めないなwww

224:デフォルトの名無しさん
08/02/22 21:43:42
プログラムを1から始めようと思うのですが、まずは本でも買って読むべきですか?
それともネットで調べるべきですか?

225:デフォルトの名無しさん
08/02/22 21:45:59
何をやりたいか目標を立てることから始めるべき。

226:デフォルトの名無しさん
08/02/22 22:16:13
文字列sに含まれる先頭のcの添字を表示させる関数を作れ
cが無い場合は、-1を表示

という問題で詰まってます
文字列の中のcを認識させるにはどうすればよいのでしょうか


227:デフォルトの名無しさん
08/02/22 22:22:42
strchr

228:デフォルトの名無しさん
08/02/22 22:24:16
マルチで申し訳ないですが
グローバルな共用体の変数に、関数からメンバーに代入したらセグメントエラーを吐いたのですが、これは許されないのでしょうか?


229:デフォルトの名無しさん
08/02/22 22:29:20
マルチしないでください^^;

230:デフォルトの名無しさん
08/02/22 22:46:54
火星人で申し訳ないのですが
グローバルな共用体の変数に、関数からメンバーに代入してもセグメントエラーを吐かないのですが、
嫁は許してくれるでしょうか?

231:デフォルトの名無しさん
08/02/22 22:48:12
こんがらがっちゃったんで、聞きたいんですが・・・
今こんなテンプレートクラスがあったとして
template<typename T>
class Array{
  T *array;
  size_t length;
public:
  Array(size_t n = 0){...}
  ~Array(){...}
  T& operator [](size_t n){...}
}
これを
typedef Array<myclass> MyArray;  //myclassは適当なクラスということで
Array<MyArray> MyArray2(2);
と使う時、MyArray2は与えた引数で初期化できますが
MyArrayの方にコンストラクタの引数を与える場合はどうすればいいですか?
ちなみにこれは、配列クラスなんでできれば、MyArray2が持つそれぞれのArray<myclass>に
別々の初期化パラメータを与えたいんですが・・・。

232:デフォルトの名無しさん
08/02/22 22:49:58
>>255
何ができるかを伝えてあげるべき。
ようこそプログラムの世界へ。

233:デフォルトの名無しさん
08/02/22 22:50:25
>>225だったorz


234:デフォルトの名無しさん
08/02/22 22:51:22
>>227
それは関数そのものではないでしょうか
わざわざ教えたいただいたのですが、伝達不足でした、すみません
int strch_idx(const char* s, char c);
という関数の雛形が与えられて、この中身を作るのに、cを認識する必要があると判断したのですが、間違っているでしょうか

235:デフォルトの名無しさん
08/02/22 22:54:41
>>231
今のC++では無理だね。だからSTLコンテナではreserveしてpush_backしたり、
組込の配列からコピー初期化したりする。

236:デフォルトの名無しさん
08/02/22 22:56:20
>>234
cを認識の意味がわかりません
s内からcを検索したいってこと?

237:デフォルトの名無しさん
08/02/22 23:17:22
>>235もしやと思ったらやっぱりですか・・・
この場合大人しくループまわして作ることになるんでしょうね。
ありがとうございました。


238:デフォルトの名無しさん
08/02/22 23:34:21
>>236
例えば、sという文字列にcincoと入力すると、1を
sという文字列にiicicoと入力すると3を
sという文字列にnorioと入力すると-1をreturnで返却する

こういう関数を作ろうと思うと、sという文字列の中身について、
s[0]に格納されているのはcかどうか、s[1]に格納されてるのはcかどうか、s[2]に格納されているのは…
と、ひたすら繰り返して行く必要があると考えました
そのためには、s[n]について、cなのかどうか判定する必要があるのではないかと
この判定というのが、認識と同じ意味のつもりで使いました

239:デフォルトの名無しさん
08/02/22 23:40:52
strchrのソース読めよ。
検索すればいくらでも出るだろ

240:デフォルトの名無しさん
08/02/22 23:45:33
>>238
if (s[0] == 'c') return 1;
if (s[1] == 'c') return 2;
if (s[2] == 'c') return 3;
...and so on.

241:デフォルトの名無しさん
08/02/22 23:50:48
>>234
学校の宿題は自分でやれよ。屑

242:デフォルトの名無しさん
08/02/23 00:02:06
>>238
それ以外に方法はstrchrを使用するぐらいしか思いつかない
(strchrもおそらくは、中で同じようなことしてると思うけど)

なにが疑問なのかよくわからないので、とりえあず2通りソースを貼り付けときます

int i;
for(i=0; s[i] != '\0' && s[i] != c; i++);
return s[i] != '\0' ? i : -1;


char *p;
return (p=strchr(s, c)) != NULL ? (int)(p-s) : -1;

返ってくるのは配列の添え字ですのであしからず

243:デフォルトの名無しさん
08/02/23 00:06:01
>>239  >>240
どうも、理解できました

>>242
ご丁寧にどうもありがとうございました

244:デフォルトの名無しさん
08/02/23 03:34:24
全くコードの書き方が分からないので質問させて下さい。
C++ VS2005

略)
printf("Got: %02x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3], buf[4]);


buf[0]には01
buf[1]には06
buf[2]には17
buf[3]にはf3
buf[4]には34
が入る。

を文字列"0106171f34"に置き換えたい。

1.このbuf[]の中(16進数)を文字列に変換したい。

2.文字列に変換した後に、buf[0]~buf[5]を繋げたい。

sprintとかを使えば良いみたいなのですが、どのようにやってよいか分からずに困っています。
どうかよろしくお願いします。

245:デフォルトの名無しさん
08/02/23 03:35:36
>>244
課題を丸投げしたいなら宿題スレにいけ

246:デフォルトの名無しさん
08/02/23 03:37:49
>>244
いや一応答えると
sprintじゃなくてsprintfだな
sprintfで連結もできます

247:244
08/02/23 03:51:48
>>245-246
ありがとう。もうちょい試して無理だったら、宿題ではないんだけど、宿題スレで質問してみたいと思います。

248:デフォルトの名無しさん
08/02/23 03:54:12
sprintf のヘルプ見るだけで解決だろ

249:244
08/02/23 08:58:16
>>248
なんとか解決しました。時間かかった>< やってみれば、なんと簡単なコードって感じですけど。

ヘルプのみかたってイマイチわからないんですけど、ヘルプの見方の解説サイトとかってありませんでしょうか?

250:デフォルトの名無しさん
08/02/23 09:49:02
>>249
manコマンドのことなら、man manでOK。

251:デフォルトの名無しさん
08/02/23 10:05:35
Cをずっとやってたのですが、
VC++6.0でデバッグしてると、関数に入るだけでESPが100バイトくらい進みます
C++だとモジュール毎にスタックをこんなに食うものなのでしょうか?
デバッグ情報か何かで食ってるのですか?

252:デフォルトの名無しさん
08/02/23 10:06:37
ローカル変数たくさん使ってるんじゃないの

253:デフォルトの名無しさん
08/02/23 10:06:52
>>251
ローカル変数が100バイトほどあるんじゃなくて?

254:251
08/02/23 11:07:16
いやひとつもないのだが・・・
家のPCでためしたけど、
関数にステップインするときはESPは4バイトしか進まないが、
そこから1step進めて、{から関数内の1行目に入るときに、
80バイトも食う
char a[100];と宣言を入れると、これが180バイトになるから、やり方は間違ってないはず
この80バイトが何なのかわからん

255:デフォルトの名無しさん
08/02/23 11:21:13
メンバ関数とかじゃなくて?

256:デフォルトの名無しさん
08/02/23 11:22:06
>>254
一時オブジェクトの置き場になってるとか?
関数の戻り値のオブジェクトを別の関数に直接渡してる場合とか・・・
アセンブラコード出させて見ても使われてなさげ?

257:要は、ソースも出さずにあれこれ言われてもしらねーよっと
08/02/23 11:24:15
まさかとは思うが、スタックオーバフローのチェックコードが入っているとか。
さもなければalloca()相当のコードが入っているとか。
あーそうそう、この場合のローカル変数は、Cのコード上現れるものに限らず
コンパイラが必要とした一時変数も含めてってことね。
例えば、構造体を値渡ししていたりreturnで戻していると作られるかもね。

258:251
08/02/23 11:32:53
void test()
{
char a[100];
printf ("test");
}

int main(int argc, char* argv[])
{
test();

return 0;
}

コードはこれだけなんだけど。C++じゃねーな。
混合モードで見ると、これが原因らしいが、何でこんなことしてるのかな。
アセンブラわからん。

sub esp,0A4h

259:デフォルトの名無しさん
08/02/23 12:57:17
>>249
VC++ なら sprintf とか入力して F1 推せば見れるだろ。

260:デフォルトの名無しさん
08/02/23 12:58:29
>>258
デバッグ用じゃなくてもそうなら、
例外用のコードなのかもしれないな。

261:デフォルトの名無しさん
08/02/23 13:01:09
>>258
手元の2005EEで試したが、リリースビルドの規定値では該当のコードは生成されない。
デバッグビルドだと生成されるが、「基本ランタイムチェック」を無効にしたら配列分だけになった。
つまり、>257の1行目だね。

262:デフォルトの名無しさん
08/02/23 13:23:22
C言語でポインタを値渡しするにはどうすればいいですか?

263:デフォルトの名無しさん
08/02/23 13:24:01
訂正
C言語でポインタを参照渡しするにはどうすればいいですか?

264:デフォルトの名無しさん
08/02/23 13:25:31
>>263
ポインタのポインタを使う
int **p;みたいなの

265:デフォルトの名無しさん
08/02/23 13:25:41
C言語には参照渡しの機能はありません。
ポインタを渡すことで参照渡し「っぽいこと」はできるので、
ポインタのポインタを渡せばポインタの参照渡し「っぽいこと」はできます。

266:デフォルトの名無しさん
08/02/23 13:26:02
参照渡しだって結局アドレス渡しの糖衣みたいなもんなんじゃねえの

267:デフォルトの名無しさん
08/02/23 13:32:22
文脈で「参照」の意味の違いを読み取れよ

268:デフォルトの名無しさん
08/02/23 13:32:28
サンクス

269:デフォルトの名無しさん
08/02/23 13:37:01
C++じゃなくてCならアドレス渡しと参照渡しは同義で通じるだろ

270:デフォルトの名無しさん
08/02/23 13:38:30
結局やってることは同じじゃねえの

271:243
08/02/23 13:45:44
やっぱりうまくいきませんでした
何が間違っているのか、理解できません
添削をお願いしたいです
c++、Borland C++5.5.1 for win32でやっています
int strch_idx(const char* s, char c)
{
int i = 0;
while(s[i])
{
if(s[i] == 'c') goto end;
else if(s[i] == 0)
{
i = -1;
goto end;
}
i++;
}
end:
return i;
}

272:デフォルトの名無しさん
08/02/23 13:50:02
最近はソフトウェア工学も学ばないのか

273:デフォルトの名無しさん
08/02/23 13:51:13
>>271
>if(s[i] == 'c') goto end; 

'c' じゃなくて c では?
あと、else if (s[i] == 0) の判定をする前に while の条件で抜けてしまうかと

274:デフォルトの名無しさん
08/02/23 13:55:02
>>266>>269>>270
そういう不正確な事やってると
>>207 みたいな奴が出てくるんだよ。

275:デフォルトの名無しさん
08/02/23 14:11:18
>>274
俺はCでの話を言ってるんだぞ?
アドレス渡ししかないんだからないんだから、不正確もなにもねぇだろうが

276:デフォルトの名無しさん
08/02/23 14:12:17
Cには参照なんてないんだからそんな言葉つかうなよ。

277:デフォルトの名無しさん
08/02/23 14:13:07
え?マクロは参照じゃないの?

278:デフォルトの名無しさん
08/02/23 14:15:15
C言語は基本的にすべてコピーで渡す
ポインタもコピー

279:デフォルトの名無しさん
08/02/23 14:15:51
>>275
C には参照渡しなんてないんだよ。

280:デフォルトの名無しさん
08/02/23 14:18:09
参照渡しがアドレス渡しの糖衣ってのは正しい
どっちかだけ知らずに語ると馬鹿なことになるけど、どっちもしっかり理解してるなら別に問題ないでしょう

281:デフォルトの名無しさん
08/02/23 14:20:52
static_castと(int)みたいなキャストってなにかなにか違うんですか?

282:デフォルトの名無しさん
08/02/23 14:24:24
>>281
static_castの方が用途が限定される


283:デフォルトの名無しさん
08/02/23 14:24:35
>>280
個人がそう理解するのはかまわんけど、初心者への説明としては不親切じゃね?

284:デフォルトの名無しさん
08/02/23 14:25:07
>>281
Cとの互換性を大事にしたいなら後者、意味をはっきりさせたいのなら前者を使うといいでしょう。

285:デフォルトの名無しさん
08/02/23 14:26:18
>>273
実際やってみると
cuで2が、gguで3が、ijcoで4が返ってきます
これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね?
しかし、while関数自体は終わってるので、s[i]は判定されている
どういうことなんでしょうか?
また、ご指摘を受けて、whileをdo-whileに変更しました、ありがとうございます

286:デフォルトの名無しさん
08/02/23 14:27:11
なんでそんな単純な構造でgotoを使う必要があるのか解らん。

287:デフォルトの名無しさん
08/02/23 14:30:00
gotoは怖くて使えない・・・
てか絶対使わないようにしてるんだが、違うのか

288:デフォルトの名無しさん
08/02/23 14:31:58
>>280
単なる構文糖衣じゃない。
参照の参照というのは存在しないが、
ポインタのポインタというのは存在する。
これは大きな違いで、適当な教え方してると >>207 みたいなやつが出てくる。

289:デフォルトの名無しさん
08/02/23 14:33:55
>>287
むしろ使った方が綺麗になる状況では使う。
でも、上のは break; 使えば解決できることで、
goto を使って解決すべきじゃない。

290:デフォルトの名無しさん
08/02/23 14:37:52
>>282
>>284
当面はあまり気にしなくてよさそうですね
どうもありがとうございました

291:デフォルトの名無しさん
08/02/23 14:39:03
>>290
いいや、気にしろ。

292:デフォルトの名無しさん
08/02/23 14:42:06
普通は C 風のキャストは使うべきじゃない。
せいぜいクラスのテンポラリオブジェクトを作るのに関数風のキャストを使うくらい。

293:デフォルトの名無しさん
08/02/23 14:47:55
>>292
それはキャストよりもコンストラクタ呼び出しのほうがしっくりくる

294:デフォルトの名無しさん
08/02/23 14:49:30
昨日質問したものですが、char * 型とchar []を判別する方法はありませんか?

295:デフォルトの名無しさん
08/02/23 14:52:19
ソースコードを読みましょう。

296:デフォルトの名無しさん
08/02/23 14:54:36
>>291
すいません
気にしろとだけ言われましてもなにに気を使えばいいのかわかりません

まずい点でもでてくるのか
だとかを教えていただけませんか

297:デフォルトの名無しさん
08/02/23 14:58:13
キャストには色々意味があって、C言語風キャストだとそれらをすべて内包してしまって意図が掴みにくい


298:デフォルトの名無しさん
08/02/23 14:58:20
メインウインドウにBUTTONを作成するときなどで使う、
CreateWindowとCreateControlWindowはどう違いますか?

299:デフォルトの名無しさん
08/02/23 15:00:58
>>296
C風のキャストはなんでもかんでもキャストできてしまうので、
プログラマの意図と違ってても警告が出ない

const void *p = ~;
char *q = (char*)p; // charにキャスト・・・あれ? constも外しちゃったよ! でも警告は出ない
char *r = static_cast<char*>(p); // コンパイルエラー: static_castでconstは外せない
char *s = const_cast<char*>(static_cast<const char*>(p)); // constも外したい意図の場合はこう書く

300:デフォルトの名無しさん
08/02/23 15:03:54
>>286-287
gotoのほうが行き先が明確になるので、理解しやすかったので、用いていますが
なぜ怖いのでしょうか
それと、「これは、s[i] == cと、s[i] == 0の判定が成されていないという事ですよね?
しかし、while関数自体は終わってるので、s[i]は判定されている
どういうことなんでしょうか? 」
これにも答えていただけると非常にありがたいです


301:デフォルトの名無しさん
08/02/23 15:04:05
>>296
キャストというのは基本的にマズい処理。
アップキャストだけは例外的に安全だが、
それ以外は基本的にはあまりやるべきではない。

でも、実際にはどうしてもやる必要が出てくる事もある。
こればっかりは仕方が無い。
そういう時、C 風のキャストを使ってしまうと色々と問題が発生する。

・ 間違って危険なキャストをしてしまうかもしれない。
 例えば、const を付けるべきところで const を付け忘れたり。
 こういう時、static_cast なら危険な const の付け忘れがあるとコンパイルエラーになる。
 C 風キャストだと問答無用でキャストされてしまう。
 これが一番の問題。

・ キャストが原因っぽいバグが見つかった時、どこにキャストがあるのか探すのが面倒。
 C++ のキャストだと検索でキャストを行っている箇所を簡単に見つけられる。

・ キャストがあまり目立たない。
 危険な処理を行っている箇所が目立たないのは危険。
 C++ のキャストは非常に目立つ。

・ 打鍵数が少ないので気軽にキャストをしてしまう。
 C++ のキャストは打ち込むのが面倒で、キャストを本当に使うべきなのか
 立ち止まって考えるよう思考を誘導してくれるかもしれない。

・ 今行おうとしているキャストはどういうものかをあまり意識しないかもしれない。
 キャストという処理を軽く見ているのはよろしくない。

302:デフォルトの名無しさん
08/02/23 15:06:01
>>300
gotoが必要になるのは言語の構造化能力を超えた構造が必要になる場合であって、
この場合はそういう場合でない。

303:デフォルトの名無しさん
08/02/23 15:06:12
>>300
論理的に記述しようぜ。
「while を終了する」 と 「指定位置に移動する」 では
前者の方がより論理的だ。
論理的なコードは、一般に変更に強く、バグが出にくい。

まあ、break すらみだりに使うべきじゃないという人もいるけどね。

304:デフォルトの名無しさん
08/02/23 15:07:50
関数の引数で、char * 型とchar []型を判別する方法ありますか?

305:デフォルトの名無しさん
08/02/23 15:09:39
>>304
不可能

306:デフォルトの名無しさん
08/02/23 15:10:05
void foo(char* const& hoge);
template <size_t N> void foo(char (&hoge)[N]);

と区別できなくはない。

307:デフォルトの名無しさん
08/02/23 15:12:02
char[N]とchar[]は別物だと思うよ。

308:デフォルトの名無しさん
08/02/23 15:12:33
void foo(char* hoge, size_t size);
template <size_t N> inline void foo(char (&hoge)[N]) { foo(hoge, N); }

もちろん、こう実装するんだぜ。

309:デフォルトの名無しさん
08/02/23 15:13:12
そう言う意味での char [] 型なんてそもそも存在しないが。

310:デフォルトの名無しさん
08/02/23 15:13:14
>>285
>cuで2が、gguで3が、ijcoで4が返ってきます

その書き方はおかしい
strch_idxには引数が2つあるので、cuとかgguだけでは結果は決まらないはずだ

311:デフォルトの名無しさん
08/02/23 15:13:24
>>300
逆。
gotoの方がどこにでも飛ばせるせいで行き先が不明確になる。

自分の書いたコードを他人に読ませることを想像してごらん。
breakならどこに飛ぶのか一目瞭然だけど、gotoだといちいちラベルを検索しないといけない。
しかもbreakなら「ループの終了」という意図が一目瞭然だけど、
gotoだとどういう意図で飛ばしたのかを考えないといけない。
そういう理由でgotoは避けられるため、安易にgotoが入っているとさらに、
「gotoを使わなければいけないどんな理由があったのか?」と考えさせることになる。

312:デフォルトの名無しさん
08/02/23 15:14:13
int⇔floatの変換だけでも、毎回static_cast使う?
あと、コンテナの最後の要素以外を処理する時、
std::vector<T> container;
for (int n = 0; n < static_cast<int>(container.size()) - 1; ++n) container[n] = ...;
ってやる?

313:デフォルトの名無しさん
08/02/23 15:23:01
>>312
俺はstatic_castを使う
コンテナの方は
for (size_t n = 0; ~
って書けばいいのでは
本当は std::vector<T>::size_type の方が適切なのかもしれんが

314:デフォルトの名無しさん
08/02/23 15:23:54
>>312
>int⇔floatの変換
うん。
>最後の要素以外を処理
unsigned使う。

315:デフォルトの名無しさん
08/02/23 15:31:10
>int⇔floatの変換だけでも、毎回static_cast使う?
使う。

>コンテナの最後の・・・
for (std::vector<T>::size_type n = 0, size = container.size(); n + 1 < size; ++n) container[n] = ...;
ってやると思う。
符号無しの値を符号付きにキャストするのは基本的に危険だと思う。

316:デフォルトの名無しさん
08/02/23 15:32:52
後者の場合、
if( !c.empty() )
for( size_t n=0; n<c.size()-1; ++n)
で何か問題あるのか?

317:デフォルトの名無しさん
08/02/23 15:34:18
>>316
n + 1 < c.size() で判定すれば empty チェックは要らない。

318:デフォルトの名無しさん
08/02/23 15:36:12
typename 忘れてた。
まあ T をそういう意味で使ってるとは限らないが。

319:デフォルトの名無しさん
08/02/23 15:39:01
>>302 >>303
>>311での説明とほぼ同じという理解でよろしいでしょうか

>>311
gotoよりbreakを使うべきというのは、よく理解でき、納得できました
しかし、怖いというのは一体

>>310
すみませんが、もうすこし噛み砕いて説明願えないでしょうか
const char* sには、任意の文字列が入って、char cで、検索する文字を固定という事ではないんですか?
そのconst char* sにcuですとか、gguですとかが入っているので、これで十分だと考えているのですが

320:デフォルトの名無しさん
08/02/23 15:43:08
>>319
goto はまず特定の状況でしか使われない。
それ以外で使われると混乱するし、
何のために使われているかすぐに分からないので不気味で怖い。

321:デフォルトの名無しさん
08/02/23 15:44:11
>>319
goto は意図が不明確。
goto のあるコードを変更することになった場合、
その意図が 100% 分からなければ、
手を加えて変なことになりかねないので怖い。

322:デフォルトの名無しさん
08/02/23 15:44:56
>>319
一番怖いのは、バグの温床になること。
コードの分かりにくさってのはバグに直結する。

323:デフォルトの名無しさん
08/02/23 15:47:14
>>315
イテレータ使うならこうだな。
前進イテレータでさえあれば、これでいけるはず。

if(! container.empty()) {
 Iter it_next = container.begin();
 ++it_next;
 for(Iter it = container.begin(), end = container.end(); it_next != end; ++it, ++it_next) *it = ...;
}

324:デフォルトの名無しさん
08/02/23 15:52:18
>>319
const char* s が cu でも c の方は
strch_idx("cu", 'c') とか
strch_idx("cu", 'u') とか
strch_idx("cu", 'x') とか色々指定できるわけで

325:デフォルトの名無しさん
08/02/23 15:53:30
>>320-322
なるほど、よく理解できました
ご親切にありがとうございます
1、意図が不明で不気味で怖い
2、バグを招きやすいから怖い
この二点ですね

そして、本筋のほうもできたら説明していただきたいのですが

326:デフォルトの名無しさん
08/02/23 15:53:54
STLつかうとコンパイルに時間かかりますけど、クラスも多少鈍くなるんですか?

327:デフォルトの名無しさん
08/02/23 15:58:00
そもそも while じゃなくて for 使おうぜ。

328:デフォルトの名無しさん
08/02/23 15:58:55
>>326
一般に、コンパイルに時間がかかる方が、
コンパイル時にある程度処理を行ってくれているため、速くなる。
ただ、コードがあまりにも肥大してくると、
キャッシュの効きが悪くなって遅くなる事もある。

329:デフォルトの名無しさん
08/02/23 16:02:03
>>325
いくつか修正したみたいだけど今はどうなってるの?

330:デフォルトの名無しさん
08/02/23 16:05:44
>>324 >>329
最初から全文現すべきでしたね、申し訳ありません
#include <iostream>
using namespace std;

int strch_idx(const char* s, char c)
{
int i = 0;
do {
if(s[i] == c) goto end;
else if(s[i] == 0)
{
i = -1;
break;
}
i++;
} while(s[i]);
return i;
}

int main()
{
cout << "文字列を入力:"; char p[] = ""; cin >> p;
char c = c; cout << strch_idx(p, c);

return 0;
}
>>327
forだと、終了させるための条件が思いつかなかったので、whileにしましたが、やはりforのほうが良い理由があるのでしょうか

331:デフォルトの名無しさん
08/02/23 16:07:30
>>330
>char c = c;
これはなによ

332:デフォルトの名無しさん
08/02/23 16:08:43
>>330
continue した時でもインデックスが増えてくれるのと、
インデックスをなめていく操作を行っているという意図が伝わりやすいのと。

終了条件は while の時と同じでいいじゃん?

333:デフォルトの名無しさん
08/02/23 16:16:31
>>330
goto end ってどこに飛んでるの?

334:デフォルトの名無しさん
08/02/23 16:17:17
>>330
goto endが一個消し忘れ。

×char c = c;
○char c = 'c';

-1を返したいのは文がヌル文字だけだった場合?それとも文字が見つからなかった場合?
前者ならループのたび判定するのは無駄だから最初に一回だけ判定させたらいい。
後者ならヌルが見つかった時点でループが終わってるから中のlese-if節は判定してくれない。
最初に文字列の長さを測って最後までループが回った場合に-1を返すようにしないと。

335:デフォルトの名無しさん
08/02/23 16:26:11
f(x)のあとでstrlen(ch)が1になることがあります もとのソースを簡略にしました
構造体を参照渡ししてもだめでした 下は期待通りの動作をします 何がいけないのかわかりません

#include <string.h>
#include <stdio.h>
typedef struct STRDATA{ char *start; char *end;}strdata;

f(strdata x){
delete x.start;
x.start = new char [20];
strcpy(x.start,"++++++++++++++"); }


main(){
char *ch=new char [10]; strcpy(ch,"uuuu");

strdata x;
x.start=ch; x.end=ch+strlen(ch);
f(x);
printf("%s",ch);}

336:デフォルトの名無しさん
08/02/23 16:26:35
なんで do-while になってるんだろう。
もっと単純に考えようぜ。

まず、文字を1つずつ取得していくループを書く。

for(i = 0; /* 文字列が終了するまで */; i++) {
 /* s[i] で文字を先頭から順番に走査していける */
}

んで次に、c が見つかったらインデックスを返すようにする。

for(i = 0; /* 文字列が終了するまで */; i++) {
 /* s[i] が c なら i を返す */
}

そして、検索しても c が見つからなかった場合は -1 を返す。

for(i = 0; /* 文字列が終了するまで */; i++) {
 /* s[i] が c なら i を返す */
}
/* -1 を返す */

これでおk。

337:デフォルトの名無しさん
08/02/23 16:29:05
>>304

Cならシーキビだろ
C++か?

template<typename T>
struct IsArray {
enum { value = 0 };
};

template<typename T, size_t N>
struct IsArray<T[N]> {
enum { value = 1 };
};

template<typename T>
bool test(const T&) {
return IsArray<T>::value;
}

template<typename T>
void f(const T& t) {
if(test(t)) cout << "配列だ" << endl;
else cout << "配列じゃない" << endl;
}

338:デフォルトの名無しさん
08/02/23 16:29:46
てか、C++ならブースト使えよか

339:デフォルトの名無しさん
08/02/23 16:30:19
>>335
f の呼び出し後、ch は既に delete された後のアドレスを保持することになるから
絶対にアクセスしちゃダメ。

そもそも生のポインタで確保されたメモリを扱ってるからそういう事が起きる。
コンテナ使え。

340:デフォルトの名無しさん
08/02/23 16:30:21
これだとエラーで止まります どうすればいいですか

f(strdata *x){
delete x->start;
x->start = new char [20];
strcpy(x->start,"++++++++++++++"); }


main(){
char *ch=NULL;

strdata x;
x.start=ch; x.end=ch+strlen(ch);
f(&x);
printf("%s",ch);}

341:デフォルトの名無しさん
08/02/23 16:31:18
>>335
chに割り当てたnew char[10]はfの中でdeleteされてるから、
printf("%s",ch) は違法。

それからnew[]した配列はdeleteではなくdelete[]しないといけない。

342:デフォルトの名無しさん
08/02/23 16:34:08
>>340
char *ch=NULL;
x.end=ch+strlen(ch);

ヌルポインタに整数を足しても有効な値にはならない。

343:デフォルトの名無しさん
08/02/23 16:35:22
バイナリ文字列の始めと終わりを構造体で渡して、内容、サイズを書き換えるには
>>335をどう変更すればできますか?

344:デフォルトの名無しさん
08/02/23 16:37:35
普通に先頭のポインタとstrlen使って適当に操作したらいいんちゃう?

345:デフォルトの名無しさん
08/02/23 16:38:25
バイナリ・・・文字列??

それはともかく、std::string 使え。

#include <string>

void f(string& str) {
 str = "++++++++++++++";
}

int main() {
 std::string str("++++");
 printf("%s\n", str.c_str());
 f(str);
 printf("%s\n", str.c_str());
}

346:デフォルトの名無しさん
08/02/23 16:38:32
このふたつは動きますが内容が変化しません なぜですか

f(strdata x){
delete x.start; x.start = new char [20];
strcpy(x.start,"++++"); }


main(){
char *ch=NULL;

strdata x;
x.start=ch;
f(x);
printf("%s",ch);}



f(strdata *x){
delete x->start; x->start = new char [20];
strcpy(x->start,"++++"); }


main(){
char *ch=NULL;

strdata x;
x.start=ch;
f(&x);
printf("%s",ch);}

347:デフォルトの名無しさん
08/02/23 16:38:49
1つ目、std:: 忘れた。

348:デフォルトの名無しさん
08/02/23 16:41:16
C言語だけで、0を含む文字列を変化させたいのですが、できないですか?

349:デフォルトの名無しさん
08/02/23 16:42:49
>>346
ポインタが参照渡しでどうのこうの言ってた奴だよな?
頼むからポインタとは何かを一から勉強し直してくれ。

350:デフォルトの名無しさん
08/02/23 16:44:23
>>346
関数に渡された数値は数値がコピーされただけの別物。
だから関数内でx.start = new char [20];とかやっても呼び出し元のxには変化は無い。

351:デフォルトの名無しさん
08/02/23 16:44:32
f(x)で、(バイナリ)文字列を書き換えられるやり方教えてください それみて勉強します

352:デフォルトの名無しさん
08/02/23 16:45:30
>>351
まともな本読め。
そこにいくらでもサンプルは書いてあるし、
詳細な解説も載ってる。

353:デフォルトの名無しさん
08/02/23 16:46:24
>>350 
後者はアドレス渡しですけど・・・

354:デフォルトの名無しさん
08/02/23 16:47:42
>>353
後者では x は書き換えられるが ch は書き換えられない。

355:デフォルトの名無しさん
08/02/23 16:47:47
>>353
アドレスの指す先の内容を書き換えると呼び出し元へ反映されるというだけのこと。

356:デフォルトの名無しさん
08/02/23 16:50:34
x->start = ch
ってやっても、ch と x->start がリンクされるわけじゃない
x->start の内容が変化しても、chには関係ない

357:デフォルトの名無しさん
08/02/23 16:52:12
これで正解でしょうか?


#include <string.h>
#include <stdio.h>
typedef struct STRDATA{ char **start; char **end;}strdata;

f(strdata x){
delete *(x.start); *(x.start) = new char [20];
strcpy(*(x.start),"++++++++++++++"); }


main(){
char *ch=NULL;

strdata x;
x.start=&ch;
f(x);
printf("%s",ch);}

358:デフォルトの名無しさん
08/02/23 16:52:50
図を描こうぜ。図を。
ch, x, そして動的に確保されたメモリが
実際にメモリ上でどう置かれていてどう参照していて
何を実行するとどう変化するか。

359:デフォルトの名無しさん
08/02/23 16:54:53
>>357
それでとりあえずまともに動くね。
推奨されるコードかと言うとまたそれは別だが。
new 使ってるから C++ なんでしょ? コンテナ使えば楽だぜ。

360:デフォルトの名無しさん
08/02/23 16:58:05
横から質問で申し訳ないんだけど、

・>357のfに渡す前に、xはいつnewされてるの?
・関数の一行目がdeleteって、ものすごく気持ち悪いんだけど、よくつかう手法なの?

361:デフォルトの名無しさん
08/02/23 17:00:09
>>360
deleteにNULLを渡しても何も起こらないことになっているから、
最初にnewされていないというのは大丈夫。エラーにはならない。

最初にdeleteというのは必要に応じて使えばいいと思うけど、
俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。

362:デフォルトの名無しさん
08/02/23 17:03:44
サンクス たびたびどうもありがとうございます

363:デフォルトの名無しさん
08/02/23 17:04:30
俺も横レスだけど、配列なのに delete [] にしてないのは問題ないのか?

364:デフォルトの名無しさん
08/02/23 17:04:41
>>363
大問題。

365:デフォルトの名無しさん
08/02/23 17:05:56
だからコンテナを使おうぜと言ってるのに。

366:デフォルトの名無しさん
08/02/23 17:06:16
いろいろな意味で気持ち悪い。というか何をしたいのかよくわからない。

367:デフォルトの名無しさん
08/02/23 17:07:46
>361
>deleteにNULLを渡しても何も起こらないことになっているから、
>最初にnewされていないというのは大丈夫。エラーにはならない。
なるほど、どうもです。

>最初にdeleteというのは必要に応じて使えばいいと思うけど、
>俺も書いた覚えない(clear()とかいかにもそれだけを行う関数というのでもない限り)。
なるほど。
よく考えたらC++になってからnewなんてほとんど使ったこと無かった気がします。
動的な配列が必要になったらだいたいvectorにつっこんでた。

368:デフォルトの名無しさん
08/02/23 17:10:42
clear はメモリが解放される訳じゃないんだよな。
std::vector<int>().swap(v); みたいにしないとメモリは解放できない。
解放した方がいいかどうかは状況次第だが。

369:デフォルトの名無しさん
08/02/23 17:32:26
>>364
大問題ってことで軽くググってみたら、
・配列に対して、delete [] としなかった場合、1個目の要素のみデストラクタが走り、残りの要素は走らない
・確保された領域(配列)は一応開放される(デストラクタで開放されるべき領域は除く)が、
 要素数保持のための隠れた確保領域は開放されずに残る

ってな、感じかな

370:デフォルトの名無しさん
08/02/23 17:37:02
勘違いしてないか?タスクマネージャで確認してみ


#include <stdio.h>
main(){
char *ch=new char[200*1024*1024];
getchar();
printf("delete 実行\n");
delete ch;
getchar();}

371:デフォルトの名無しさん
08/02/23 17:40:15
これでも解放するし

#include <stdio.h>

main(){
int n;
char **ch=new char*[200];
for(n=0;n<200;n++)ch[n]=new char [1024*1024];
getchar();
printf("delete 実行\n");
for(n=0;n<200;n++)delete ch[n];
getchar();}

372:デフォルトの名無しさん
08/02/23 17:42:39
>>331
strch_idx関数に渡すためのcを、main関数のほうで作っておかないとだめかなと考えまして

>>332
あまり理解できませんが、なるべくforを使うようにします

>>333
消し忘れです
ご指摘ありがとうございます

>>334
理屈を丁寧に解説していただきありがとうございました
>>336を参考にやってみて、できました

>>336
ご丁寧にありがとうございました
その指針でできました


最後にご丁寧に、教えるのもわずらわしいような初歩的な愚問に答えていただき、ありがとうございました

373:デフォルトの名無しさん
08/02/23 17:44:35
これが初心者歓迎スレの良心。

374:デフォルトの名無しさん
08/02/23 17:47:40
>>370
>>371
特に勘違いしてるところはないと思うが・・・

要素数を保持する領域はないってことを言いたいのか?
組み込み型にはないけど、クラスにはあるみたいなことが書いてあったんだが

375:デフォルトの名無しさん
08/02/23 17:49:37
これだと解放しないけど・・・ *xと定義されているなら、deleteを使うのでは? []は**xを解放する場合でしょ

#include <stdio.h>
main(){
char **ch=new char*[200];
for(int n=0;n<200;n++)ch[n]=new char [1024*1024];
getchar(); printf("delete 実行\n");
delete[] ch; // delete ch;
getchar();}

376:デフォルトの名無しさん
08/02/23 17:50:41
>>369
そもそもnew[]したものをdeleteするとどうなるかは未定義。
そういう挙動になったという話は、たまたまその実装ではそうだったということでしかない。

377:231
08/02/23 17:51:43
今更ですが>>231のようなことをした時に
MyArrayの方はデフォルトコンストラクタか引数を省略できるコンストラクタを
呼んでいるようなのですが、これのタイミングが分かりません。
コンストラクタを通過するそぶりもないし、一応初期化はされてるっぽいし・・・
特にデストラクタのタイミングも分からないのが心配です。
いつ開放されるんでしょうか?

378:デフォルトの名無しさん
08/02/23 17:54:33
>>377
どこかでnew[]やdelete[]しているだろ?そのときだ。

379:デフォルトの名無しさん
08/02/23 18:04:57
>>375
newで割り当てたものはdelete、new[]で割り当てたものはdelete[]で解放します。参照の深さは関係ありません。

380:デフォルトの名無しさん
08/02/23 18:12:04
終端をセットしたいのですがどうやったらいいですか? コンパイルが通りません

main(){
char *ch=new char [50];
char **start, **end;

start=&ch; //これは成功します

end=&&ch[20];
// end=&(ch+20);

}

381:デフォルトの名無しさん
08/02/23 18:24:57
ch と &ch[0]は同じアドレスを表しますよね 20個目のアドレスは、&ch[20]ですよね
それを参照渡ししようとしたら&&ch[20]のはず・・・

382:デフォルトの名無しさん
08/02/23 18:26:38
char * chend = &ch[20];
end = &chend;

383:デフォルトの名無しさん
08/02/23 18:33:33
>>382
コンパイルはできましたが、startと動作が違うようです 

main(){
char *ch=new char [50]; strcpy(ch,"abcdef");

char **start, **end;

start=&ch;

char * chend = &ch[20];
end = &chend;


printf("%c\n", ((*start+1)[2]) );

printf("%c\n", ((*end-5)[2]) );
}

384:デフォルトの名無しさん
08/02/23 18:34:48
間違えました 20個を定義していませんでした
これだとうまくいきました サンクス

char * chend = &ch[6];
end = &chend;


printf("%c\n", ((*start+1)[2]) );
printf("%c\n", ((*end-5)[2]) );

385:デフォルトの名無しさん
08/02/23 18:38:15
なぜ「end = &&ch[20];」というか「end = &(&ch[20]);」ができないかは理解しておいてね。

386:デフォルトの名無しさん
08/02/23 18:41:41
再使用できるように動的確保したら複雑になってきました・・・

main(){
char *ch=new char [50]; strcpy(ch,"abcdef");
char **start, **end;
start=&ch;
char **chend =new char *;
*chend=&ch[6];
end = &(*chend);
printf("%c\n", ((*end-5)[2]) );
}

387:デフォルトの名無しさん
08/02/23 18:43:04
先ずお前はnewを使うのをやめろ。話はそれからだ。

388:デフォルトの名無しさん
08/02/23 19:53:27
これはひどい

389:デフォルトの名無しさん
08/02/23 20:04:00
何がしたのか全然わからない

390:デフォルトの名無しさん
08/02/23 20:04:21
何度基礎をやり直せと言ったことか

391:デフォルトの名無しさん
08/02/23 20:26:55
なぜ、再使用しようとすると動的確保することになるのかもわからない。
文章で理由を説明してほしい。


392:デフォルトの名無しさん
08/02/23 20:36:55
なるほど、stringが出来るわけだ

393:デフォルトの名無しさん
08/02/23 20:53:56
おまえらほんと我慢強いよな。感心するよ
俺は>>386と同レベルのコードを保守する羽目になって殺意を覚えた。

394:デフォルトの名無しさん
08/02/23 21:00:35
我慢強いというか、読んでない

395:デフォルトの名無しさん
08/02/23 21:02:02
C++の授業で先生が、
int main() {
int i;
cin>>i;
double a[i];
...
というコードはC++では出来ない(やりたいならnewでやるべき)と言われたのですが、
g++とiccではできました。これってだめだけど、gccやiccの拡張機能によって
できているのでしょうか?



396:デフォルトの名無しさん
08/02/23 21:04:05
>>395
C++ が変化し続けているだけの話

397:デフォルトの名無しさん
08/02/23 21:09:33
>>395
現状のC++標準規格じゃ無理。C99は可能。
C99サポートしてるコンパイラなら期待してもいい。

398:デフォルトの名無しさん
08/02/23 21:11:02
newも使うべきではないよな。いやnew[]ではなくてstd::vector。

399:デフォルトの名無しさん
08/02/23 21:13:17
C99は正直あんまやらないでほしい

400:デフォルトの名無しさん
08/02/23 21:18:40
可変引数マクロはマジホシス

401:デフォルトの名無しさん
08/02/23 21:24:18
0xでおk

402:デフォルトの名無しさん
08/02/23 21:35:03
おしえてください  下から2行目を動かすとデータが壊れるのですが原因がわかりません

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct STRDATA{ char **st; char **end; }strdata;

f(strdata x){ printf("%s",*(x.st)); }

strconv(strdata *q, char **p){
char **chend =(char **)malloc(sizeof(char **));
q->st=p;
*chend=&(*p)[strlen(*p)];
q->end = &(*chend);}

strconstconv(strdata *q, char *p){
int n=strlen(p);
char *ch=(char *) malloc(n+1);
strcpy(ch,p);
q->st=&ch;
char **chen =(char **)malloc(sizeof(char **));
*chen=&(ch[n]); q->end = &(*chen);}

main(){
strdata str;
#define STR "abcdefgh"
strconstconv(&str, STR); //ここをコメントアウトして一つ下を動かしても平気です
//char *ch=new char [50]; strcpy(ch,STR); strconv(&str,&ch);
//char *x=new char [1];  ここを動かすとおかしくなります
f(str); }

403:デフォルトの名無しさん
08/02/23 21:37:15
もうお前いい加減諦めたら。

ローカル変数のアドレスを関数外に持ち出すな。

404:デフォルトの名無しさん
08/02/23 21:39:05
char *x=new char [1]; が、なぜstrdata strを書き換えられるんでしょうか?

405:デフォルトの名無しさん
08/02/23 21:39:21
なんかまぁ・・・・・・いろいろとおつかれさん

406:402
08/02/23 21:45:20
おなじやつですが短くしました 下から2行目を動かすと壊れるのはなぜでしょうか

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct STRDATA{ char **st; char **end; }strdata;

f(strdata zzz){ printf("%s",*(zzz.st)); }

strconstconv(strdata *q, char *p){
int n=strlen(p);
char *ch=(char *) malloc(n+1);
char **chen =(char **)malloc(sizeof(char **));
strcpy(ch,p);
q->st=&ch;
*chen=&(ch[n]); q->end = &(*chen);}

main(){
strdata str;
strconstconv(&str, "abcdefgh");
// char *test=new char [1];
f(str); }

407:デフォルトの名無しさん
08/02/23 21:46:36
まず変数のスコープを勉強しよう

408:402
08/02/23 21:48:09
なぜコメントアウトを外すとデータがこわれますか?

409:デフォルトの名無しさん
08/02/23 21:53:31
newやmallocの確保は、解放しない限り残るんですよね そのアドレスは参照で受け取っているので問題ないと思うのですが
参照渡しにしてもだめです

f(strdata *zzz){ printf("%s",*(zzz->st)); }

main(){
strdata str;
strconstconv(&str, "abcdefgh");
f(&str); }

410:デフォルトの名無しさん
08/02/23 21:54:33
基礎からやりなおせよ

411:デフォルトの名無しさん
08/02/23 21:56:58
ヒントください

412:デフォルトの名無しさん
08/02/23 21:57:01
いいから基礎からやりなおせって。スタックとヒープの概念すら分かってないだろ。

413:デフォルトの名無しさん
08/02/23 21:57:11
>>409
トリップをつけてくれるとあぼーんしやすいのですがいかがでしょうか

414:デフォルトの名無しさん
08/02/23 22:00:25
スタックとかヒープとか、この際関係ないレベルじゃん

415:デフォルトの名無しさん
08/02/23 22:02:39
より短くしました これでも外すと壊れます なぜですか?

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; char **end; }strdata;

f(strdata *q){
char *ch=(char *) malloc(10);
strcpy(ch,"abcdef");
q->st=&ch; }

g(strdata *zzz){ printf("%s",*(zzz->st)); }

main(){
strdata str; f(&str);
//char *test=new char [1];
g(&str); }

416:デフォルトの名無しさん
08/02/23 22:03:36
>>409
多少手を入れて(int mainとするとか)こっちで動かしてみましたが、ちゃんとabcdefghと表示されました。

でも、newだけc++の機能をつかってるけど、あとは全部(結構年季が入った感じの)cだし、
c++のコンパイラなら、関数の戻り値を指定しないのはダメだと思うし、
mallocとnew は併用したらダメだってどこかで聞いたけどな。

いまいちやろうとしていることの意図がつかめません。
(mallocとnewを併用して、どういう状況でまずいのかしらべようとしているのか)

もしc++を勉強しようとしているなら、なにか適当な本とかで勉強するのを勧めます。
Cを上記くらいご存知なら、すぐにC++も使えるようになりますよ。


417:デフォルトの名無しさん
08/02/23 22:03:53
ヒントもなにも>>403がずばり回答してるんだが。
これでもわからないなら、なんでもいいからポインタの無い言語に行ってくれ。
そして帰ってくんな。

418:デフォルトの名無しさん
08/02/23 22:08:06
>>415
なんでお前は答えを貰っても全くレスポンスを返さずに、
そんなヘドロみたいなコードを貼り続けるんだ。

頭沸いてるのか

419:デフォルトの名無しさん
08/02/23 22:08:35
>>415
これなら動く。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
    char *st;
    char *end;
} strdata;

void f(strdata *q) {
    char *ch=(char *)malloc(10);
    strcpy(ch,"abcdef");
    q->st = ch;
}

void g(strdata *zzz) {
    printf("%s", zzz->st));
}

int main() {
    strdata str;
    f(&str);
    g(&str);

    return 0;
}

420:デフォルトの名無しさん
08/02/23 22:11:12
>>419
おまいやさしいな

421:デフォルトの名無しさん
08/02/23 22:14:15
>>419
それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります 
削ったのですがこれでも原因が不明です コンパイラはBCC5.5です

#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; }strdata;

f(strdata *q){
char *ch=(char *) malloc(10);
ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0;
q->st=&ch; }

main(){
strdata str; f(&str);
//char *test=(char *) malloc(1);
printf("%s",*(str.st));}

422:デフォルトの名無しさん
08/02/23 22:17:54
>それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります 

( ゚д゚) ・・・
 
(つд⊂)ゴシゴシ
 
(;゚д゚) ・・・
 
(つд⊂)ゴシゴシゴシ
  _, ._
(;゚ Д゚) …!?

423:デフォルトの名無しさん
08/02/23 22:17:55
419でどこの文字列がどう書き換えられないっていうんだ言ってみろ

424:デフォルトの名無しさん
08/02/23 22:20:55
VCCやGCCやDMCでも実行中にエラーになります

#include <stdio.h>
#include <stdlib.h>
typedef struct { char **st; }strdata;

void f(strdata *q){
char *ch=(char *) malloc(10);
ch[0]='X';ch[1]='Y';ch[2]='Z';ch[3]=0;
q->st=&ch; }

int main(){
strdata str;
char *test;
f(&str);
test=(char *)malloc(1);
printf("%s",*(str.st));
getchar(); return 0;}

425:デフォルトの名無しさん
08/02/23 22:21:34
>>421
>それだと、ポインタは値渡しのため、strに渡した文字列が書き換えられなくなります 
wwwwwwwwwwwwwwwwwwwwwww
>>419よ、これが現実だwwwwwアホは相手にするなwwwwww


426:デフォルトの名無しさん
08/02/23 22:22:15
ぶっちゃけポインタ全く理解してないだろ。

427:421
08/02/23 22:26:27
誤解していましたすみません 

428:デフォルトの名無しさん
08/02/23 22:28:05
さすがに・・・

初心者を抜け出した程度の俺でも酷いと思うw

429:デフォルトの名無しさん
08/02/23 22:28:08
>>424
変数testの用途が不明だったので、削除させてもらった。

#include <stdio.h>
#include <stdlib.h>
typedef struct {
    char *st;
}strdata;

void f(strdata *q) {
    char *ch = (char *)malloc(10);
    ch[0] = 'X';
    ch[1] = 'Y';
    ch[2] = 'Z';
    ch[3] = '\0'; //まあ0のままでもいいんだけど
    q->st = ch;
}

int main() {
    strdata str;
    f(&str);
    printf("%s", str.st);
    getchar();
    free(str.st);
    return 0;
}


430:421
08/02/23 22:28:56
すみません 誤解していませんでした 書き換えられません

#include <string.h>
#include <stdio.h>
typedef struct { char *st; }strdata;

f(strdata *x){
delete x->st;
x->st = new char [9];
strcpy(x->st,"++++++"); }

main(){
char *ch=NULL;
strdata x;
x.st=ch;
f(&x);
printf("%s",ch);}

431:デフォルトの名無しさん
08/02/23 22:34:49
>>430
お前が421や424で書いたコードは
>printf("%s",*(str.st)); 
だったのになぜ
>printf("%s",ch);
になってるんだ?納得のいく説明を聞こうか?

432:デフォルトの名無しさん
08/02/23 22:34:55
>>429
int main() {
strdata str;
f(&str); ←ここで初期化された文字列の内容、長さを変更したいんです あと変数testほ確保しても落ちないようにしたいんです
printf("%s", str.st);

みなさんは、>>424はまともに動きますか?

433:デフォルトの名無しさん
08/02/23 22:37:26
>>432
動かすまでもなく、まともに動かないのは分かる

434:430
08/02/23 22:37:28
>>335>>343>>348>>351がもともとの質問でこれを実現したいんです

435:デフォルトの名無しさん
08/02/23 22:37:36
>>430
printf("%s",ch);をprintf("%s",x.st);とすればいい。
嫌か?
じゃあこれでどうだ。
#include <string.h>
#include <stdio.h>
typedef struct {
    char *st;
} strdata;

void f(strdata *x) {
    delete x->st;
    x->st = new char[9];
    strcpy(x->st,"++++++");
}

int main() {
    char *ch = NULL;
    strdata x;
    x.st = ch;
    f(&x);
    ch = x.st;
    printf("%s",ch);
    delete[] ch;

    return 0;
}

436:デフォルトの名無しさん
08/02/23 22:39:36
>>433
test=(char *)malloc(1);をはずすと上手くいきます なぜですか

437:デフォルトの名無しさん
08/02/23 22:40:58
>>436
それは上手く動いてるんじゃなくて、たまたま動いてるだけ

438:デフォルトの名無しさん
08/02/23 22:41:46
>>335
をチラ見しかしてないけどそれが動くことがとても不思議。
とりあえず期待する動作はなんなのかを日本語で書いてください。

439:デフォルトの名無しさん
08/02/23 22:42:06
>>435
それだと始めにchが巨大に確保されていたらメモリーリークになると思うのですが

440:デフォルトの名無しさん
08/02/23 22:43:20
>>436
偶然。

あのコードでは、すでになくなったローカル変数を読み取ろうとしている。
運良くメモリ上に残っていれば、一見正しく動いているように見える。
そのtestの行は、残っていた変数の値を破壊する決定打になったのだろう。

441:デフォルトの名無しさん
08/02/23 22:43:21
>>439
思うだけだ

442:デフォルトの名無しさん
08/02/23 22:44:24
見る気もしない。
高速スクロールで華麗にスルー。
違うお題ないの?

443:デフォルトの名無しさん
08/02/23 22:46:11
Perlで言うところの

use LWP::Simple;
sub foo{ return get('URLリンク(hoge.com)'); }

これをVC++で極力シンプルにやるにはどうすればいいでしょうか?
環境は以下のとおりです。

VisualC++.net2003 Standard
managedC++不使用 MFC不使用 ATL/WTL使用 STL/Boost使用

444:デフォルトの名無しさん
08/02/23 22:46:57
>>438
バイナリ文字列 (\0を含む) の初めと終わりを構造体で関数に渡して、バイナリ文字列の内容、長さを書き換えたいんです

445:444
08/02/23 22:48:45
純粋なC言語だけでそれを実現したいんです 

446:デフォルトの名無しさん
08/02/23 22:49:59
>>445

一般的に知られている C言語の定義とは違うものを扱ってらっしゃるのですね

447:デフォルトの名無しさん
08/02/23 22:50:53
最終的には、C言語のみにしますけど今は実験段階なので・・・

448:デフォルトの名無しさん
08/02/23 22:52:02
>>444
なんでchとかtestとか別の変数が出てくるの?
構造体のまま扱い続ければいいでしょ。

449:443
08/02/23 22:54:26
>>443
単純にC++でネット上のものをダウンロードさせるには
どうすればいいですか?って聞くべきだった orz

450:デフォルトの名無しさん
08/02/23 22:55:14
chは現物の文字列です この初めと終わりのアドレスを構造体で渡して変化させるようにしたいんです

451:デフォルトの名無しさん
08/02/23 22:55:32
本でも読んで出直してこいよ
本格的に他人に頼りたいなら金でも払え

452:デフォルトの名無しさん
08/02/23 22:59:15
現物の文字列ってなんだよ
ただのポインタだろ
str.st と等価だ

453:デフォルトの名無しさん
08/02/23 23:01:55
たとえば、
char *ch=new char [100]; strcpy(ch, "---------");
という文字列に対して、その先頭と後方のアドレスを関数に渡して、関数側で書き換えられるようにしたいんです

454:デフォルトの名無しさん
08/02/23 23:04:50
何にそんなもんをつかうんかわからんが
とりあえずそんなことを考える前に
入門書なりきちんと読め。
たのむから

455:デフォルトの名無しさん
08/02/23 23:09:26
初めの文字列が200M程度確保されていたとして作業領域も200M使うとします
このとき初めの文字列を解放するか、上書きすれば最高でも400Mしかメモリを使いません
しかし、それができずに返却すると最大 200M + 200M + 200M必要になります

456:デフォルトの名無しさん
08/02/23 23:11:03
>>449
ソケット使ってカリカリやるしか思いつかん

457:デフォルトの名無しさん
08/02/23 23:11:12
>>443
手軽さならWinInet
真剣にやるならWinsock

458:デフォルトの名無しさん
08/02/23 23:13:38
>>450
435みたいに、構造体で渡した後、元の変数に代入し直せばいい。

459:デフォルトの名無しさん
08/02/23 23:15:30
もはやポインタいらんがなw

460:デフォルトの名無しさん
08/02/23 23:19:19
文字列ではなく、1byte変数の配列を可変長で扱いたいと。
だったら、
typedef struct {
char *baka;
size_t length;
} aho;

とでもして、構造体をやり取りすればいいだろ。
C++だったら、vector<char>、deque<char>でも使えや。

461:443
08/02/23 23:20:13
WinInetででググったらいっぱい出てきたんで調べてみる。
サンクス

462:デフォルトの名無しさん
08/02/23 23:20:26
>>443
URLDownloadToFile

463:デフォルトの名無しさん
08/02/23 23:26:44
>>458
なぜ直接書き換えられないのかわかりません

464:デフォルトの名無しさん
08/02/23 23:29:10
>>463
こっちからしてみたら、なんで構造体を使いたくないのかわからない。

465:デフォルトの名無しさん
08/02/23 23:29:25
>>463
もっと勉強してから出直せ

466:デフォルトの名無しさん
08/02/23 23:40:17
もともと構造体は使っていますよ あとC言語のみで動かせるようにしたいんです
開始のアドレスと長さを渡しても上と同じだと思います

467:デフォルトの名無しさん
08/02/23 23:41:34
あぼーんしたいからトリップつけてくれ

468:デフォルトの名無しさん
08/02/23 23:44:18
たぶんトリのつけ方を知らない。
「名前欄にレス番つけること」すら今日知ったっぽい

469:デフォルトの名無しさん
08/02/23 23:44:39
釣りだろう

470:デフォルトの名無しさん
08/02/23 23:46:32
文字列を入力して、
表示するとき右から3文字ごとにコンマをつける方法ってどうすれば?
(例:入力>>344fru38fh4tgiur
   出力>>3,44f,ru3,8fh,4tg,iur)
この続きお願いします・・
#include <iostream.h>
main()
{
char a[50] ;
cout <<"aに文字を入力してください>>" ;
cin.getline(a, 50) ;

int a_count = 0 ;
while( a[a_count] != '\0'){
a_count++ ;
}

cout <<"aを表示します→" ;
for(int i=0 ; i<a_count ; i++){
cout << a[i] ;
}
}


471:デフォルトの名無しさん
08/02/23 23:48:55
これがたまたまうまく動いたりしますが、実際は間違っているから困っているんです

#include <stdio.h>
#include <string.h>
typedef struct { char *start ; char *end; } bin;

void f(bin *x) {
delete x->start;
x->start = new char [3];
strcpy(x->start,"aa"); }

main() {
char *ch = new char [2];
strcpy(ch,"a");
bin x;
x.start=ch; x.end=ch+strlen(ch);
f(&x);
printf("%s",ch);
}

472:デフォルトの名無しさん
08/02/23 23:50:11
>>470
URLリンク(www.google.co.jp)

473:デフォルトの名無しさん
08/02/23 23:53:13
x.start=ch; とした時点で、数値がコピーされるだけになり、文字列を書き換えられなくなります
だから x.start=&ch;と参照渡しをするために
構造体を { char **start ; char **end; }に変更します
そうすると上記のような現象が出ます

474:デフォルトの名無しさん
08/02/23 23:53:48
>>471
f(&x);
ch=x.start;
printf("%s",ch);
でいいだろ
って・・・釣られちまったよ~~~~ん

475:デフォルトの名無しさん
08/02/23 23:56:53
>>473
fを呼んだあとのchが指す先はfの中でdeleteされていることに気づいているか?

476:475
08/02/23 23:57:42
×>>473
>>471

477:デフォルトの名無しさん
08/02/24 00:03:07
>>475
>>471ではdeleteやnewが効かない場合があるんです これはちゃんと表示されますか?

#include <stdio.h>
#include <string.h>
typedef struct { char *start ; char *end; } bin;

void f(bin *x) {
delete x->start;
x->start = new char [3];
strcpy(x->start,"aa"); }

main() {
char *ch = NULL;
bin x;
x.start=ch;
f(&x);
printf("%s",ch);}

478:デフォルトの名無しさん
08/02/24 00:06:58
Cで動くようにしたいとかホザいておきながら、new や deleteを使うバカ
しかも、

baka = new aho[shine];

としたら

delete []baka;

とすることしら知らないバカ。
マニュアルでも読め

479:デフォルトの名無しさん
08/02/24 00:07:28
>>477
じゃあもういいから、こうしとけ
#include <stdio.h> 
#include <string.h> 
typedef struct { char **start ; char **end; } bin; 

void f(bin *x) { 
delete[] *x->start; 
*x->start = new char [3]; 
strcpy(*x->start,"aa"); } 

void g(bin *x) {
delete[] *x->start; 
*x->start = new char [3]; 
strcpy(*x->start,"bb"); } 

main() { 
char *ch = NULL; 
bin x; 
x.start=&ch; 
f(&x); 
printf("%s",ch);
g(&x); 
printf("%s",ch);
}
これで終了、もう来るな

480:デフォルトの名無しさん
08/02/24 00:08:23
>>477
deleteもnewも効いているはずだよ?

・chが指す先をdeleteしようが、x->start=new・・・をしようが、chの中身は変わらない。
・deleteしても絶対に書き込めなくなるとは限らない。

これらは理解している?

481:not 477
08/02/24 00:10:08
>>478
あ・・・そういえばdelete []baka;としないといけなかったんだ・・・・
C厨ですまん。

482:デフォルトの名無しさん
08/02/24 00:15:24
構造体はCでないというつもりか?

483:デフォルトの名無しさん
08/02/24 00:17:32
>>477
main関数内、chだけに注目すれば、
chはNULLで初期化された後、一切変更を受けないだろ。
printfにNULLを渡しているので、未定義。

484:デフォルトの名無しさん
08/02/24 00:18:48
>>479
それだと、 bin x;を初期化する関数と、適当な配列を入れるとバグるんです なんでうごかないんですか

#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;

void f(bin *x) {
delete[] *x->start;
*x->start = new char [3];
strcpy(*x->start,"aa"); }

void h(bin *x){
char *ch=new char [3];
ch[0]='X';ch[1]=0;
x->start=&ch; }

main() {
bin x;
h(&x);
f(&x);
char *test=new char [1];
printf("%s",*(x.start));
}

485:デフォルトの名無しさん
08/02/24 00:23:27
バグるじゃ分らんだろ。

486:デフォルトの名無しさん
08/02/24 00:24:02
>>484
h内のローカル変数chのアドレスをx->startに格納しているが、
chはhを抜けると無くなるので、x->startは存在しない場所を指している。

487:デフォルトの名無しさん
08/02/24 00:24:26
>>484
じゃあこれでいいだろう
#include <stdio.h> 
#include <string.h> 
typedef struct { char **start ; char **end; } bin; 

void f(bin *x) { 
delete[] *x->start; 
*x->start = new char [3]; 
strcpy(*x->start,"aa"); } 

char *ch;
void h(bin *x){ 
ch=new char [3]; 
ch[0]='X';ch[1]=0; 
x->start=&ch; } 

main() { 
bin x; 
h(&x); 
f(&x); 
char *test=new char [1]; 
printf("%s",*(x.start)); 
}

488:デフォルトの名無しさん
08/02/24 00:25:03
char *test=new char [1];をのぞくと、bcc5.5では動作します
ほかのコンパイラでは、入れなくても実行時に落ちます 原因は何ですか?

489:デフォルトの名無しさん
08/02/24 00:25:46
いいように使われてるぞ、デバッグ隊w

490:デフォルトの名無しさん
08/02/24 00:27:01
>>488
原因はchがローカル変数だからだ

491:デフォルトの名無しさん
08/02/24 00:27:09
>>488
OSが落ちろ!!って指令を下すからじゃないかな?

492:デフォルトの名無しさん
08/02/24 00:27:09
おまいらまだ付き合ってやってんのか
こいつ分かってるけど、分からないフリしてるだけだろ

493:デフォルトの名無しさん
08/02/24 00:28:09
>>492
こっちも暇だからね

494:デフォルトの名無しさん
08/02/24 00:28:54
バカは放置汁。
最初の例から考えると、文字列定数や、文字配列をもdeleteしようとしてるんだから。


495:デフォルトの名無しさん
08/02/24 00:30:19
>>486>>487
しかし、これはどのコンパイラでも正常に動きませんか? C++ですが

#include <stdio.h>
#include <string.h>

void h(char *&x){
char *ch=new char [11];
strcpy(ch,"ABCDEFGHIJ");
x=ch; }

main() {
char *x;
h(x); printf("%s",x); }

496:デフォルトの名無しさん
08/02/24 00:31:31
>>495
それが動くのはchar*&だからだ

497:デフォルトの名無しさん
08/02/24 00:32:23
>>495
うん。それはローカル変数アドレスを取る(ポインタを取る、参照を取る)
ということをやっていないから問題ない。

498:デフォルトの名無しさん
08/02/24 00:33:28
>>495
そのhは、chの「値」をコピーしているので、
chが無くなっても値はxに格納されているから動く。
>>484はchの「アドレス」を格納しているだけ。

499:デフォルトの名無しさん
08/02/24 00:33:34
>>488
プログラミングは諦めたほうがいい
1.簡単な事をややこしくして
2.バグを入れて
3.聞きまくることで他人の邪魔をする

別の仕事探せ

少なくともオレはそれを勉強熱心とはいえない

500:デフォルトの名無しさん
08/02/24 00:41:03
だから、バカは放置だって。
手段に固執して、何の目的でそのイミフな手段をとろうとしているのか自分でわかってない。


501:デフォルトの名無しさん
08/02/24 00:41:58
確認したいのですが、newは、deleteするかプログラムが終了するまで解放されないはずですよね?
タスクマネージャで確認するとf()を抜けてもメモリはそのままです

#include <stdio.h>

f(){
char *x=new char [200*1024*1024]; }


main() {
f();
getchar();
}

502:デフォルトの名無しさん
08/02/24 00:42:13
>>495
ちなみに、それをポインタを使って書き直すとこうなる。
#include <stdio.h>
#include <string.h>

void h(char **x) {
    char *ch = new char[11];
    strcpy(ch, "ABCDEFGHIJ");
    *x = ch;
}

int main() {
    char *x;
    h(&x);
    printf("%s",x);

    return 0;
}

503:デフォルトの名無しさん
08/02/24 00:43:28
だからローカルで定義された変数や配列でも、そのアドレスが判明していれば、main()などで操ったり解放できますよね

504:デフォルトの名無しさん
08/02/24 00:46:04
>>503
マニュアル嫁
ヒープの意味を理解してからnew や delete を使え。
変数の記憶クラスを理解しろ


505:デフォルトの名無しさん
08/02/24 00:47:43
ローカル定義は外に抜けたら、内容が残っている保証はない
allocしたなら残っているけど

506:デフォルトの名無しさん
08/02/24 00:48:18
>>503
だからの前後が繋がってないぞ
newした領域がdeleteされるまで解放されなかったら
なぜローカルで定義された変数や配列をmainから操れることになるんだ

507:デフォルトの名無しさん
08/02/24 00:49:11
なぜですか? 間違っていないと思いますよ これはmain()側で解放してます

#include <stdio.h>
#include <string.h>

void h(char **x) {
char *ch = new char[200*1024*1024];
*x = ch; }

main() {
char *x;
h(&x);
getchar();
delete x;
getchar();}

508:デフォルトの名無しさん
08/02/24 00:52:46
>>507
それはhのローカルで定義された変数chをmainから操ってるわけではないな
単にnewした領域へのポインタchをmainのxにコピーして渡してるだけだ

509:デフォルトの名無しさん
08/02/24 00:54:23
一度目のキー入力で、200M分メモリを解放しますよ タスクマネージャみてください

510:デフォルトの名無しさん
08/02/24 00:54:39
伸びがいいから何かと思ったら未だ相手にしてたのか。

511:デフォルトの名無しさん
08/02/24 00:55:37
>>507
newで確保したメモリへのポインタをmainに連れて行っているだけ。
newやmallocで確保したメモリはソース上のスコープに縛られずに使える。

一方、>>484では、x->start=&ch;というように、
ローカル変数へのポインタをmainへ持って行っている。
しかし、mainに戻ったときには既に変数chそのものが居なくなっているのでうまくいかない。

512:デフォルトの名無しさん
08/02/24 00:56:05
見事な無自覚の自己中心主義だな、早く治せよ

>>507
なにしてるかわかってるならいいけど、ポインタ一回お浚いしたら?

513:デフォルトの名無しさん
08/02/24 00:56:26
>>507
あんたはnewで確保した領域と、それを指すポインタ変数を、同一のものであると勘違いしてないか?
>>507のコードでも、ポインタ変数chはhを抜ける時に消滅するのは分かるか?

514:デフォルトの名無しさん
08/02/24 01:00:53
まずchar *x の xは、int xや float xと同じで、ただのローカル変数であることを覚えとけ

515:デフォルトの名無しさん
08/02/24 01:04:18
しかしこれは動きません

#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;

void h(bin *x){
char *ch = new char[11];
strcpy(ch, "ABCDEFGHIJ");
*(x->start)=ch; }

main() {
bin x;
h(&x);
printf("%s",*(x.start));
}

516:デフォルトの名無しさん
08/02/24 01:04:59
>

517:デフォルトの名無しさん
08/02/24 01:05:04
free(p)ってやるとpがNULLになるとか思っちゃう人なのかな。

518:デフォルトの名無しさん
08/02/24 01:05:45
お前らバカの相手すんなって。つけあがるから。

519:デフォルトの名無しさん
08/02/24 01:06:51
>>515
x->startをまったく初期化しないまま、*(x->start)なんかに代入しているのが間違い。
>>513に答えろ

520:デフォルトの名無しさん
08/02/24 01:08:18
俺結構ポインタの理解があやふやで、だからなるべくポインタのややこしい部分には触れないプログラム今までしてきたんだけど、
このスレ読んだらなんとなく理解できてきた気がする。
C言語でnewとdeleteを使い続けてる人ありがとう!
あと、もちろん解説してくれてるみんなもありがとう!
明日からもstringばりばり使っていこうと思います。

521:デフォルトの名無しさん
08/02/24 01:09:24
>>515
そうだね、それは動かないね
だから?
何を聞きたいのか明確に

522:デフォルトの名無しさん
08/02/24 01:09:53
ポインタ変数が消滅するのはわかります
関数での、初期化と書き換えをする方法がわかりたいです

523:デフォルトの名無しさん
08/02/24 01:10:25
>>515
#include <stdio.h>
#include <string.h>
typedef struct { char **start ; char **end; } bin;

void h(bin *x) {
char *ch = new char[11];
strcpy(ch, "ABCDEFGHIJ");
*(x->start)=ch; }

int main() {
bin x;
char *p;
x.start = &p;
h(&x);
printf("%s", p);
delete[] p;
}


524:デフォルトの名無しさん
08/02/24 01:10:30
new/deleteを使うということは当然C++だよな?
じゃあ、なんでメモリ操作を隠蔽するクラスを作ろうとしないの?
IQ低いから?

525:デフォルトの名無しさん
08/02/24 01:10:53
>>522
みんなが何回も例を出しているのに・・・(T_T)

526:デフォルトの名無しさん
08/02/24 01:12:15
>>524
上のほうで最終的にCで書くと言っていたはず。
俺にはなんで今はnew[]使ってC++にするのか理解できないけど。

527:デフォルトの名無しさん
08/02/24 01:12:50
>>522
おまいがポインタについて知っている知識をすべて述べよ

528:デフォルトの名無しさん
08/02/24 01:12:53
>>522
何度か出てる正しく動く例が気に入らない理由はなぜかね

529:デフォルトの名無しさん
08/02/24 01:18:03
仮に、彼へC言語ポインタ完全制覇を与えたとしても、
それでわかってくれるかどうか不安になる。

530:デフォルトの名無しさん
08/02/24 01:19:41
>>522
皆が何言ってるかほとんど分からないC++素人だけど
一日ぐらい気分変えて犬の散歩にでも行ったら?
まあ、犬のウンコの処理しながら考えたりさ
その後で、また一から作ってみる
以外とできるかもよ

531:デフォルトの名無しさん
08/02/24 01:21:40
>>523
それだとうごきました サンクス

x.start = &p;
h(&x);
printf("%s", *x.start);

初めにメモリ上にchar*型が確保されないと受け取れないって事か


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch