C言語なら俺に聞け 144
■ このスレッドは過去ログ倉庫に格納されています
const 無しのポインタ変数にリテラル文字列を与えると C++だと (リテラル文字列の)指し先を書き換える気あるのかボケェ と警告やエラーになるですよ Cは過去のコードの互換性の為に黙ってることが多い (けどオプションで警告したりエラーにしたりするんだっけか?) "!"!"!MOHYO!"!"!"2" 1.[[[HUn≒MUL=POSI≠MAHO+Set*HUGE=SAGE=LOGE=NOISIA=0≒1]]] 2-[[[[[[[E=RAT%2^10%SPELAn!%]&!TOWA&!PEG#!NOLNOL8!#!HYAGO!2#]1*2=1]U]S]0]O]!#PAL! 3--->PAGODOL7&!@17,2222734.15&[[[%%RENRAK6,9,99"^10"]#$11.2%}]KAIJ]{ 41.2SSS = RALQI2.β{{{RA4,0,238^97,1,$.S.L.E.I.L."Q5352.15Q"JOL"5*3>>>41 .3q}}}>1.2<0 .3φTALHOSI"0">>>105 .10<1.235<1.2>51≠52===55.632>V="E=0.835"of"1.32","632",0.683,1.end { >>779-780 Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。 例えば下は、メモ帳の実行ファイルの場所を探す resText = "" IO.popen("where notepad") { |io| resText = io.read } puts resText 出力結果 C:\Windows\System32\notepad.exe C:\Windows\notepad.exe >>779-780 Rubyではパイプラインで、サブプロセスを実行し、結果を受け取れる。 これで、サイトのHTML が取れる resText = "" IO.popen("curl サイトのURL") { |io| resText = io.read } puts "終了ステータス : #{$?}", resText >>779 system()ではなくpopen()使うと楽だ。 色々ありがとう >>785 Linuxだからそいつは無理なんだ... >>787 >>788 すまん Cは決定で、さらに言うとexecvで実行も決定なんだ 実行部のソースコードの変更はしたくないので... curl.exe を Linux で? こりゃ触っちゃダメな人だな Linux なら、curl はコマンドである。 環境変数PATH も通っている which curl で、 /usr/bin/curl >>787 これは、Windows10 のWSL 上の、Ubuntu 16.04 で、Ruby で実行したもの >>790 すまねぇ 正確に言うとcurlだった 実行ファイルってのを言いたかったんだけど紛らわしかったわ.... >>791 コマンドラインで実行をコード上からして その結果をメモリに書き込みたいって感じ int main() { char* buff[1024] execv(curl..........) } 子プロセス作成とかは書いてないけどこのexecvの結果をbuffにいれたい >>779 と >>789 は同じ投稿者なのかな? 「curl.exeをsystemコールする」という文の意味は、 実際には curl.exe でなく /usr/bin/curl かどこかの Linux のコマンド、 systemコールと言っても system() 関数でなく execv() 関数で呼ぶ、 という条件でいいの? >>793 同じです メチャクチャ困惑させてすみません そうです #include <unistd.h> #include <stdio.h> int main() { int pp[2]; pid_t pid; pipe(pp); // パイプを生成 (エラーチェック略) pid = fork(); // プロセスを複製 (エラーチェック略) if (pid > 0) { // 親プロセス: 子プロセスから情報を受け取る close(0); // 標準入力のディスクリプタを閉じる dup(pp[0]); // パイプの入力を標準入力に複製 close(pp[0]); // パイプの入力を閉じる close(pp[1]); // パイプの出力側は使わない char buf[1024]; int nbytes = read(0, buf, sizeof(buf)); // 子プロセスからのデータ受け取り printf("[%*s]\n", nbytes, buf); // 受け取ったデータの確認 } else { // 子プロセス: 外部コマンドを呼び出し、標準出力経由で親プロセスに送る char *cmds[] = { "/usr/bin/echo", "hello, darling", NULL }; // ダミーの外部コマンド close(1); // 標準出力のディスクリプタを閉じる dup(pp[1]); // パイプの出力を標準出力に複製 close(pp[1]); // パイプの出力を閉じる close(pp[0]); // パイプの入力側は使わない // 外部コマンドの呼び出し (エラーチェック略) execv(*cmds, cmds); } return 0; } 自分で fork, exec するなら pipe() 作って dup() で繋げ。 やり方はUNIXやLinuxのシステムコールに関する入門書みたいなのがあれば必ず書いてあると思うのでそういうのを見るか、またはググれば世界中で解説やサンプルプログラムが見つかると思う。 かなり基本的な事だ。 急造のデッチ上げだけど、こんな感じかな。 要点は、名前なしパイプを作って標準入出力と差し替える。 外部コマンドの標準出力はパイプを通って出ていく、 呼び出した側は標準入力を読むとパイプから入ってくる。 32行制限に収めるために行が詰めたら見にくいね。 などと書いている最中に真上にサンプルプログラム出現w curlだったら、オプションで全部ファイルに書き出せるじゃないか 親プロセス側は標準入力をパイプに差し替える必要ないね。 パイプのディスクリプタから素直に読みゃいいんだわ。 // close(0); // (不要)標準入力のディスクリプタを閉じる // dup(pp[0]); // (不要)パイプの入力を標準入力に複製 // close(pp[0]); // パイプの入力側はまだ閉じちゃダメ! close(pp[1]); // パイプの出力側は使わない // int nbytes = read(0, buf, sizeof(buf)); // (変更) int nbytes = read(pp[0], buf, sizeof(buf)); // 子プロセスからのデータ受け取り close(pp[0]); // 使用済みパイプの入力を閉じる >>801 本物らしいな しかも解説ドキュメント付 やっぱオープンソースよりプロプライエタリのほうが忖度が充実してるね 流出どころかAppleがそもそも堂々と公開してるじゃないか >>808 OSのソースコードはないじゃん(´・ω・`) まあ、ライセンスが必要な部分は非公開なんだけどね。 処理が進んでくにつれてエラー処理のif文の中身が増えていくのをどうにかしたいんだがいい方法ない? >>815 エラー時に行う定型的な処理の塊を関数化するのではいかんの? >>815 普段起こりえないエラーは全部gotoでケツに例外処理を書く >>815 あー。ファイル1を開く、エラーならリターン、ファイル2を開く、エラーならファイル1をクローズしてリターン、ファイル3を開く、エラーならファイル1、ファイル2をクローズしてリターン、 ・・・って具合にリターン直前にクローズするファイルがどんどん増えていくみたいなやつだよね? そういうのは俺はもう goto 使って関数の終わりの方に飛ばしてそこで必要なクローズやらfree()やらをまとめてやるようにしたよ。関係する変数は関数のブロックの先頭の宣言で全部 NULL や -1 で初期化して goto の飛び先で NULL や -1 でなければクローズやfree()をする。 (但し関数の途中で自分でクローズやfree()をした場合はその直後にNULLや-1を代入するように書く必要がある)。C言語は try catch みたいな例外処理は作れないから仕方がないね。 goto 使わずにやるとしたら for (;;) か while (1) のブロック内に書いてエラーが出たら break すればできる(もちろんループの終わりは break)。しかしこの方法はループでもないのにループを書くという何か不自然なものになる。 >>818 C言語の場合は同じような事をする場合はgotoの方が可読性高いと思うけどなあ。とにかく間すっ飛ばして使ったリソース開放して即リターンしたいわけだし。 >>816 それで対応できるものもあるんですけどね・・・ >>817 >>819 gotoは絶対使っちゃいけないみたいな感覚があって考えていませんでした どうしようもないときに使ってみます goto hell;はdo-whileで置き換え可能。 do { ... break; // goto hell; ... } while (0); hell:; >>823 ああ。do while で 0 で抜けるようにするのでもできるか。 まあしかし goto 使わないならそんな風にするしかないよな。 単純に置き換え可能じゃないから do while(0) は定着しなかった ※個人の感想です do while(0) も使うけど、その中でループを書く場合は面倒だからgoto使うかなあ 必ずどっちかだけってことは無いですね return は1箇所でまとめる派 (関数出口は1箇所) とっと return してしまう派 (関数出口は散らばる) cでgoto使わないのは唐揚げにレモンかけないようなもんやで break 1 とか break 2 とかで 抜ける {} の段数指定できない仕様が糞 >>823 gotoというキーワードに対する言葉狩りでしかない うちの若いのがそんな変態コード書いたらしばく do{}while(0)は普通に使うやろ 特にマクロで どこが変態やねん! int ret = 1; int fdA = -1; int fdB = -1; int fdC = -1; if (ret) { fdA = open(A); if (fdA < 0) { printf(“ファイルAオープンエラー¥n”); ret = 0; } } if (ret) { fdB = open(A); if (fdB < 0) { printf(“ファイルBオープンエラー¥n”); ret = 0; } } if (ret) { fdC = open(A); if (fdC < 0) { printf(“ファイルCオープンエラー¥n”); ret = 0; } } if (ret) { いろいろ処理 } if (fdA >= 0) close(fdA); if (fdB >= 0) close(fdB); if (fdC >= 0) close(fdC); return ret; O'ReillyのLinuxデバイスドライバ本では 初期化の失敗時、一部分だけ確保できたリソース群を 確保時とは逆順に行儀良く解放するのにgotoを使う方法を勧めてるね。 そういう具合にgotoが出てくる場面が明確ならば 必ずしもgotoが可読性を落とす、とは言えないじゃろ。 >>829 なんかの理由でネストを増やしたら全部書き換えになる糞仕様だろ ループにラベルつけてラベルを指定してbreakできるようにしてほしい >>831 使わねーよノーマルさんなら 変態の自覚がない真性変態め goto を使わないようにというのは 昔、ダイクストラ大先生が「gotoは有害だ!」 とのたまわれたので、それ以後gotoを使わない 構造化プログラミングというのが流行ってFortranなども Fortran 77で一部構造化されたりしてきたという経緯が あります。 たしかに、昔のBASICプログラムはやたらgoto が多くて まさにスパゲッティプログラムで論理を追うのに苦労しました。 最近のBasis(たとえばFree Basic)などは構造化されていて 使いやすく感じます。 Cもgotoを使わなくて書けるのですから、やむおえない (gotoを使わなければ、どうしようもない)場合場合以外は 使わないにこしたことはないと思います。 ダウト 昔のBASICはGOTO文のせいで読みづらいんじゃない 最大のネックは変数が全てグローバルであること 次いでFOR文のNEXTの自由度が高すぎることだ メインフレーム脳でPCを語るジジイどもが 行番号を批判していたが的外れもいいとこ >>833 gotoの使い道なんてそのパターン以外ないな。 Linuxカーネルで登場するgotoをざっくりgrepしてみたらラベルの種類は1000種類程度 top10は以下 12257 out 2534 err 1609 done 1520 error 1415 fail 1351 exit 737 unlock 493 retry 421 again 368 bail grepが雑すぎた 1753種でtop10は以下 2つ目のoutは先頭にスペースあり 12257 out 2534 err 1609 done 1520 error 1415 fail 1351 exit 1213 out 737 unlock 493 retry 421 again >>818 初心者…gotoを使いまくる 中級者…gotoを一切使わない 上級者…適材適所を覚える >>818 内部的には全部goto(継続とか)だって事を理解すれば、適切な使い方が出来るようになる。 ドラクエもテトリスもファイナルファンタジーも全部 C言語で作っているのですか?ふと疑問に思いました。 >>836 知識30年以上前で遅れてないか? C言語なら理由があるgoto文は普通に使われるぞ 他言語で言う例外処理機能やラベル付きbreak文が無いからな >>846 > C言語なら理由があるgoto文は普通に使われるぞ さすがにこれは言い過ぎだろう。 ただしgoto不要論も50年前の理論であり、盲信するのも間違いだというだけだ。 問題は、goto を無くしたいだけの理由で余分なフラグやループ(もどき)を導入する是非だ。 ソースが余計に見にくくなるのは事実だからね。 最近の風潮なら、linter等によって「間違ったgotoの使い方」を検出できるようになれば、 gotoは完全にありになるだろう。 問題はこれが難しい(と言うよりやる気がない)ことで、 Cのノリなら「お前が間違えなければいいだけ、何故特化文法が必要になる?」になってしまう。 ラベル付きbreakとか、導入しても俺はいいと思うけどね。 例外については、今のところ他言語でも上手い解を見つけられていない。 goto文を使った場合はあくまで自関数内のtry-catchになってしまうが、正直、これで十分だ。 OOPでの継承先からのcatchとかを許可すると、便利な反面、密結合になってしまい、 noexceptとか言いだしているし、完全にあっちは暗礁に乗り上げつつある。 Cだと最初からnoexceptしかない。OOPが色々屋上屋を架しているのも事実だね。 毎年どっかのスレでGOTO戦争起こってる気がする。 goto使えないなら、setjmpにマクロ被せてtry〜catch風にしちゃえw >>836 「gotoは有害!」と言われるそのgotoは昔のBASICみたいな、別のサブルーチンの中に無節操にジャンプできる機能のことだったんじゃないかと思われる。 関数の外に飛べないgotoなら、関数の行数が少なければさして問題じゃない。 gotoのラベルって、関数内しか有効じゃなかったっけ? こんな時代だからこそあえてmain関数にすべてを詰め込むプログラミングスタイルを確立していきたい あー。別サブルーチンにgotoあったねえ。 6502アセンブラで書かれた Apple ][ のモニタプログラムにもそういうの結構あって当時すげえとか思ったが、無理矢理2KBのROMに押し込むための苦肉の策だったんだよな。 当時はメモリが高価で少ないのが当たり前だったから何でもかんでもトリッキーな方法使って小さくしてた。 >>851 試してみ。お前のコンパイラは何か違うかも知れない。 ただし出来た場合、それをC言語と読んで良いのかどうか悩ましいところだ。 それと、一体どのようなコードを作っているのかが気になる所だな。 >>852 変なことに挑戦するなよw Cだとそれできちゃうんだからw >>836 > 昔、ダイクストラ大先生が「gotoは有害だ!」 > とのたまわれた 本人が書いたわけじゃないけどな >>851 むかーし、データ受信専用のホストアプリ作ったときは、setjmp、longjmp使ったな >>851 ああ、>>850 で書いたのはもちろんC言語のgotoじゃない。 そもそもgotoはよくないという主張が叫ばれたのが1960年代、C言語ができたのは1972年らしいんだから。 ガチの初心者で申し訳ないんやが...。 unsigned char型変数には8ビットしか入らんはずやのに 0〜255の数値が入るのはなんでなんや? 8ビットを二進数変換すると11111111でこれを10進数に変換すると255になるのは分かるんやが なぜ255の半角が入るのかがわからんのや。 #質問するとこ、ここで合ってるよな? >>859 うん、”255”の半角を入れるなら終端文字まで含めると4バイト必要だね ‘2’(0x32) ‘5’(0x35) ‘5’(0x35) ‘¥0’(0x00) >>859 君がどういう勘違いをしているのかよくわからない。 >>861 小人さんがASCIIコードに変換してる すまん、いま投稿しようと思ったら、クソ規制に弾かれたわ だから詳細が書けない。 たぶんこんな感じ 2進数で格納すると8文字(11111111) 16進数で格納すると2文字(FF) 10進数で格納すると3文字(255)分の領域が必要なはず なのになんで10進数の数値255を 1文字分の領域(unsigned char型変数)に格納できるの??? 簡単に書くわ signed char var = 255; ↑これが何故格納できるのかわからない。 >>868 さっきまでunsigned言うてたのに… >>868 signed charでは-1を意味しているけど 中身は同じ8bit(2進数で表すと11111111)だから格納はできる 何が分からないのか、それがよく分からない 1ビットなら、0,1 2ビットなら、0,1,2,3 3ビットなら、0,1,2,3,4,5,6,7 ・ ・ ・ ・ 8ビットなら、0,1,2,3,4,5,6,7.....253,254,255 指折るなりしてちょっと考えてみよう >>861 それは255という数値を "255" という文字列に変換しているね 0〜255 の「数値」は 8 ビット = 1 バイトで表現できますよ >856 Edgar Dijkstra: Go To Statement Condidered Harmful Communications of the ACM 11, 3(March 1968) 147-148 というように、ダイクストラ大先生が権威ある Communications of the ACM にお書きになっていますが。 この論文は検索すれ読めますよ。 >>868 数値としての255だからだよ。コンパイラが"255"の文字の並びを見て数値の255として扱って8bitのvarを初期化するコードを作ってくれるの。 >>877 そんなのネットですぐ分かるだろ、と「コンディダード」を検索したら 5ちゃんねるの「C言語なら俺に聞け 144」て掲示板の投稿877番がトップに出た。 最新のネット用語で言うところの「モルゲッソヨ」みたいな感じね。 >>875 だからその > Go To Statement Condidered Harmful って言うタイトルはダイクストラじゃなくてニクラウス・ヴィルト(Pascal作った人)が付けたって話な ちなみに本人がつけたタイトルは A Case Against the Goto Statement そもそも論文の中身を読めばgoto有害一辺倒でないこともわかる 読んでない知ったかさんがタイトルだけで騒ぎすぎ w ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる