今、可変長引数をBUFFERにいれて
送る(SSLを使いますが・・・)ことをしていますが、
どうしてもその部分らしいところでwarningがでます。

どうもいまいちva系の取り扱いがわからないので、
アドバイスいただけるとうれしいです。

****ソース(va系が含まれるところのみ)****

WriteToClient (fmt, va_alist)
char *fmt;
va_dcl
{
va_list ap;
char * ssl_buf[1024];

va_start (ap);
vfprintf (stdout, fmt, ap);
va_end (ap);
//SSL
SSL_write(ssl, ssl_buf, sizeof(ssl_buf) );
}

*****コンパイル後のwarningメッセージ****

/usr/local/lib/gcc-lib/i386-pc-solaris2.8/2.95.3/include/stdarg.h:96: warning: `
va_start' redefined
/usr/local/lib/gcc-lib/i386-pc-solaris2.8/2.95.3/include/varargs.h:111: warning:
this is the location of the previous definition
SSLpasschanger.c:216: macro `va_start' used with just one arg

わかる方いらっしゃいましたら、よろしくおねがいいたします。

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

A 回答 (4件)

 ん~つまり WriteToClient 関数を printf のように扱いたいってことですか?


 それでしたら、こんな感じだと思います。

void WriteToClient(char* fmt, ...)
{
 char ssl_buf[1024];
 va_list ap;

 va_start(ap, fmt);
 vsprintf(ssl_buf, fmt, ap);
 SSL_write(ssl, ssl_buf, sizeof(ssl_buf));
}

 この書き方で良かったのかどうか忘れてしまいましたが、とりあえず ap には fmt の次の引数のアドレスが入るはずです。
 ただ、va_ マクロの実装は処理系によってかなり違うと思いますから、やはり自信は無しです。

 呼び出し方は printf と同じです。フォーマットも指定してください。

WriteToClient("%s", "500 Username required.");

// "全角空白" でインデントしてますのでご注意を…もうご存知でしたね。
// No.1 で関数内に書いた ... は "省略" の意味です。なので 214 ... は必要ないです。引数リストの ... は必要です。
// それから gcc には va_alist や va_dcl というマクロもあったのですね。不勉強でした。No.1 の後半部分は忘れてください。
    • good
    • 0
この回答へのお礼

御礼が遅れてしまってすいません。
おかげさまでなんとか無事できました。

ありがとうございました!!!
とても感謝しております!

お礼日時:2002/01/27 02:23

 すみません。

書き忘れました。

 warning メッセージについてですが、stdarg.h と varargs.h で定義が重複しているのではないでしょうか。普通はヘッダファイルの中で二重定義を避けるための記述がされているはずですが、とりあえずインクルードファイルは stdarg.h の方だけで試されてみると良いと思います。
    • good
    • 0
この回答へのお礼

丁寧な説明、ありがとうございます!
すごく感動してます。
warningはきれいに消えました!(T▽T)うれし~♪

お手数ながら、その後のエラーのことも教えていただけないでしょうか?

さっそく一番下に書いていただいたもの(↓)でやってみたのですが、
208 void WriteToClient(char* fmt, va_list va_dcl)
209 {
210 char ssl_buf[1024];
211
212 vsprintf(ssl_buf, fmt, va_dcl);
213 SSL_write(ssl, ssl_buf, sizeof(ssl_buf));
214 ...
215 }

関数を呼び出すとき、引数が少ないというメッセージが帰ってきました。

342:too few arguments to function `WriteToClient'

呼び出すときは、
342 WriteToClient ("500 Username required.");
のように呼び出しているのですが・・・
printfと同じように記述すればよい、と思っていたのですが・・・ちがいますかね?
どうしたらよいでしょうか?
まだプログラミング初心者なもので・・・すいません(^-^;
お願いします。

お礼日時:2002/01/19 15:17

WriteToClient そのものが、可変引数関数になるのなら、


route156 さんの書かれた、function のように、

void WriteToClient(char *fmt, ...)

とします。まぎらわしいのですが、2つ目の引数はドットを3つ連続で書いてください。
    • good
    • 0

 うろ覚えで自信は無いのですが、va_start, va_arg, va_end は可変長引数を一つずつ取り出す場合に使ったと思います。



void function(char* fmt, ...)
{
 va_list ap;
 int param1;
 char* param2;

 va_start(ap, fmt);
 param1 = va_arg(ap, int);
 param2 = va_arg(ap, char*);
 ...
 va_end(ap);
}

 ただ、ご質問では vfprintf を使われているようですので、これは引数として va_list をそのまま受け取りますから、va_start 等は必要ないと思います。

void WriteToClient(char* fmt, va_list va_dcl)
{
 ...
 vfprintf(stdout, fmt, va_dcl);
 ...
}

 老婆心ながら WriteToClient の引数を ssl_buf にセットするのでしたら、次のようになるのでは? 他の部分がわからないので推測ですが。

void WriteToClient(char* fmt, va_list va_dcl)
{
 char ssl_buf[1024];

 vsprintf(ssl_buf, fmt, va_dcl);
 SSL_write(ssl, ssl_buf, sizeof(ssl_buf));
 ...
}

 それから、スタック上のバッファを使う時は、オーバーフローに留意された方が良いと思います。
 以上、確認はしていないので間違いがあるかもしれません。その点はお許しを。
    • good
    • 0

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

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

このQ&Aを見た人が検索しているワード

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

QSSL_connect(ssl)

お世話になっています。
VC++2005、MFC、Win7、openssl で作業しています。

Gメールから、POP3S 接続でメールを受け取りたいと考えています。
メールヘッダーの受信後に、本文を取り出す前に接続が切れます。

最初に、接続の部分ですが、問題点がありましたら、アドバイスをください。

void CSQMailBoxTreeView::GmailMailDL(){
int nReturnCode;
WSADATA wsaData;
CFileException fileExpection;
#define MAJOR_VERSION_REQUIRED 1
#define MINOR_VERSION_REQUIRED 1

struct sockaddr_in server;


std::string req; // リクエスト
std::string res; // レスポンス
std::string host_url = "pop.googlemail.com";


strcpy_s(gszGmailServerName,(LPCTSTR)oc_Gmailpop3servername);
if(strlen(gszGmailServerName)==0){
MessageBox("設定 - Gmail POP3サーバー から、\n受信メール(POP3)サーバを\n入力して下さい。","POP Server", MB_OK);
}
strcpy_s(gszGmailUserId, (LPCTSTR)oc_Gmailpop3userid);
if(strlen(gszGmailUserId)==0){
MessageBox("設定 - Gmail POP3サーバー から、\nメールサーバのユーザ名を\n入力してください。","POP User ID", MB_OK);
}
strcpy_s(gszGmailPassword, (LPCTSTR)oc_Gmailpop3password);
if(strlen(gszGmailPassword)==0){
MessageBox("設定 - Gmail POP3サーバー から、\nパスワードを入力してください。","警告 PassWord", MB_OK);
}
strcpy_s(gszGmailPOP3Port, (LPCTSTR)oc_Gmailpop3port);
if(strlen(gszGmailPassword)==0){
MessageBox("設定 - Gmail POP3サーバー から、\nポート番号を入力してください。","POP3 PortNumber", MB_OK);
}

// Prepare version for WSAStartup()
WORD wVersionRequired = MAKEWORD(MAJOR_VERSION_REQUIRED, MINOR_VERSION_REQUIRED);
// Initialize the WinSock DLL
nReturnCode = WSAStartup(wVersionRequired, &wsaData);
if (nReturnCode != 0 ){
MessageBox("Error on WSAStartup()","CheckGMail", MB_OK);
return ;
}
// Confirm that the version requested is available.
if (wsaData.wVersion != wVersionRequired){
// Version needed is not available.
MessageBox("Wrong WinSock Version","CheckGMail", MB_OK);
WSACleanup();
return ;
}

sock = socket(AF_INET, SOCK_STREAM, 0);

server.sin_family = AF_INET;
server.sin_port = htons(995);

server.sin_addr.S_un.S_addr = inet_addr(host_url.c_str());
if (server.sin_addr.S_un.S_addr == 0xffffffff) {
struct hostent *host;
unsigned int **addrptr;

host = gethostbyname(host_url.c_str());
if (host == NULL) {
return ;
}

addrptr = (unsigned int **)host->h_addr_list;
while (*addrptr != NULL) {
server.sin_addr.S_un.S_addr = *(*addrptr);
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) == 0) {
break;
}
}
if (*addrptr == NULL) {
sprintf_s(outbuf3, "Fatal error: unable to connect to the server.\n");
MessageBox(outbuf3,"Error", MB_OK);
WSACleanup();
return;// -1;
}
}
else {
if (connect(sock, (struct sockaddr *)&server, sizeof(server)) != 0){
return ;
}
}

SSL_load_error_strings();
SSL_library_init();
ctx = SSL_CTX_new(TLSv1_method());
if (ctx == NULL) {
return;// 1;
}

ssl = SSL_new(ctx);
if (ssl == NULL) {
return;// 1;
}

if (SSL_set_fd(ssl, sock) == 0) {
return;// 1;
}

RAND_poll();

while (RAND_status() == 0) {
unsigned short rand_ret = rand() % 65536;
RAND_seed(&rand_ret, sizeof(rand_ret));
}

int ev = SSL_connect(ssl);
if ( ev != 1) {
int ret = SSL_get_error(ssl, ev);
if(ret <= 0){
ERR_print_errors_fp(stderr);
return;// 1;
}
}

if (WSAAsyncSelect(sock, *this, SM_GASYNC3,
FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) == SOCKET_ERROR){
MessageBox("WSAAsyncSelect() failed","Error", MB_OK);
closesocket(sock);
sock = INVALID_SOCKET;
return;
}

gnAppState = STATE_CONNECTING;
}

お世話になっています。
VC++2005、MFC、Win7、openssl で作業しています。

Gメールから、POP3S 接続でメールを受け取りたいと考えています。
メールヘッダーの受信後に、本文を取り出す前に接続が切れます。

最初に、接続の部分ですが、問題点がありましたら、アドバイスをください。

void CSQMailBoxTreeView::GmailMailDL(){
int nReturnCode;
WSADATA wsaData;
CFileException fileExpection;
#define MAJOR_VERSION_REQUIRED 1
#define MINOR_VERSION_REQUIRED 1

struct sockaddr_in server;


...続きを読む

Aベストアンサー

RETRコマンドで読み取り完了したら、そのメールを削除して、QUITコマンドで切断していますから1通しか読み込めないのは想定内の動作のハズですけど、そこらヘンはどうなんですかね?

CSQMailBoxTreeView::GmailProcessData()の呼び出し方次第ではココも正常動作が期待できませんが…。

前回の回答でも指摘しましたが普通のPOP3で正しく動作するもの作ってからの方がいいと思われますが…。
その際、LAN内の別マシンにPOP3サーバを構築すればWireSharkなどでパケットの内容は確認できますし。
# GmailのPOP3って…bad commandで切断されるのね……

あと…MessageBox()でもろもろの通知を出すと「そこで処理が止まる」ので通信扱う場合だと問題が発生することもありますのでご注意を。
# 私ならTRACE()やその類使いますね。(Win32SDKなんでOutputDebugString()ですが…)

Qremove_copy_ifがVisualStudio2005でwarning!?

はじめまして。

C/C++での質問です。

std::remove_copy_if(,,,)を使用したところ、以下の警告が出ました。
==
warning C4996: 'std::remove_copy_if': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
==

警告を消すにはどうしたら良いでしょうか?
また、_Remove_copy_if(,,,,)というAPIを見つけましたが、ヘルプで出ません。同等の処理ができるのでしょうか??
引数がremove_copy_if()よりひとつ増えていますが、最後の引数の意味が良く分かりません。。。

詳しい方がいらっしゃいましたらご教授お願い致します。

環境はWindows2000でVisualStudio2005を使用しています。

はじめまして。

C/C++での質問です。

std::remove_copy_if(,,,)を使用したところ、以下の警告が出ました。
==
warning C4996: 'std::remove_copy_if': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
==

警告を消すにはどうしたら良いでしょうか?
また、_Remove_copy_if(,,,,)という...続きを読む

Aベストアンサー

> 警告を消すにはどうしたら良いでしょうか?

ワーニング文章中にも書いてありますが、コンパイルオプションに「-D_SCL_SECURE_NO_WARNINGS」を追加すれば、このワーニングを消すことが出来ます。

Qzlib.libとlibpng.libについて

zlib.libとlibpng.libの作成ができなくて困っております。
libpng.libでpngAPIを使うには、zlib.libが必要だということで
zlib.libのビルドにも挑戦していますがうまくいきません。
これらのファイルを作るのが目的ではないので
どなたか配布できるならば配布していただけないでしょうか?。
もし配布できないなら作り方の詳細をご教授願います。

環境
Windows VISTA SP1
Visual Studio 2008

googleで検索して出てきたHPについては
ほとんど見ましたが
それをみてやっても上記環境ではうまくビルドができません。
*例えば以下 他にもたくさんみてその通りにやりましたが
エラーが大量にでてしまいうまくいきません。
http://dencha.ojaru.jp/programs_07/pg_graphic_10a1.html

大変 レベルの低い質問ですがよろしくおねがいいたします。
m(___)m

Aベストアンサー

有名なGNUプログラムなら、GnuWin32を探せばバイナリが見つかるでしょう。
http://gnuwin32.sourceforge.net/

http://gnuwin32.sourceforge.net/packages/zlib.htm
http://gnuwin32.sourceforge.net/packages/libpng.htm

QBorlandbcc55とMYSQLのコンパイル時にlibmysql.libやmysqlclient.libのリンクについて

Windows上で、borlandbcc55、mysqlを利用しいてます。
Windows上のborlandbcc55、mysqlで
C/C++のソースでMYSQLの接続・切断・管理・MYSQLのレコードの値の取得・値の表示の仕方の基礎を教えてください。
これなら動きますよというソースを教えて頂けたら有難いです。

Borlandbcc55とmysqlの設定

my_global.hとmysql.hをincludeして、

コンパイル時にlibmysql.libやmysqlclient.libをリンクしてやればできそうなのですが

includeは
Cのソースで
#include "c:\mysql\include\mysql.h"
#include "c:\mysql\include\my_global.h"
と記述するだけでOKなのでしょうか?

MYSQLのLibmysql.libの設定の仕方及びコンパイル時にlibmysql.libやmysqlclient.libを
リンクする方法がわかりません。

bcc55コンパイラ設定のcfgファイルにlibMysql.libやmysqlclient.libを
追加設定必要ですか?
必要ならどう記述すればいいのでしょうか?
また違う仕方なのでしょうか?
全く理解できていません。
そのリファレンスをみてもわかりません。

1 coff2omf c:\mysql\lib\opt\libmysql.lib c:\borland\bcc55\lib\libmysql.lib
2 ilink32 obj-Dateien, exe-Dateiname, map-Datei, Libraries
3 -> ilink32 c0x32.obj testmysql.obj , testmysql.exe , , import32.lib cw32.lib libmysql.lib

これらの設定の仕方もわかりません。
設定に必要なのかどうかも理解できていません。
よろしくお願いします。

Windows上で、borlandbcc55、mysqlを利用しいてます。
Windows上のborlandbcc55、mysqlで
C/C++のソースでMYSQLの接続・切断・管理・MYSQLのレコードの値の取得・値の表示の仕方の基礎を教えてください。
これなら動きますよというソースを教えて頂けたら有難いです。

Borlandbcc55とmysqlの設定

my_global.hとmysql.hをincludeして、

コンパイル時にlibmysql.libやmysqlclient.libをリンクしてやればできそうなのですが

includeは
Cのソースで
#include "c:\mysql\include\mysql.h"
#inclu...続きを読む

Aベストアンサー

>includeは
>Cのソースで
>#include "c:\mysql\include\mysql.h"
>#include "c:\mysql\include\my_global.h"
>と記述するだけでOKなのでしょうか?

ダメでしたか?

cfgファイルにはよくつかうオプションを記述する。
普通は -I オプション、-L オプション。
どこにインクルードファイル、ライブラリファイルを置いてるかをコンパイラやリンカに教えるため。
よく使うのであれば追加すればいい。


>1 coff2omf c:\mysql\lib\opt\libmysql.lib c:\borland\bcc55\lib\libmysql.lib
c:\mysql\lib\opt\libmysql.lib はVisual C++用のライブラリファイルなので、coff2omfで変換しないと使えない。

>2 ilink32 obj-Dateien, exe-Dateiname, map-Datei, Libraries


>3 -> ilink32 c0x32.obj testmysql.obj , testmysql.exe , , import32.lib cw32.lib libmysql.lib
リンカを使ったことはありませんか?

>includeは
>Cのソースで
>#include "c:\mysql\include\mysql.h"
>#include "c:\mysql\include\my_global.h"
>と記述するだけでOKなのでしょうか?

ダメでしたか?

cfgファイルにはよくつかうオプションを記述する。
普通は -I オプション、-L オプション。
どこにインクルードファイル、ライブラリファイルを置いてるかをコンパイラやリンカに教えるため。
よく使うのであれば追加すればいい。


>1 coff2omf c:\mysql\lib\opt\libmysql.lib c:\borland\bcc55\lib\libmysql.lib
c:\mysql\...続きを読む

Qscanf("%s", buf);でスペースを含んだ文字

コンソールプログラムで
scanf("%s", buf);
を使用してユーザに入力された文字によって処理を行いたいのですが、このままではスペースを含む文字列がスペースの手前で切られてしまいます。
C:\Program Filesなどを入力可能にさせたい場合にはどのようにするのがベターですか?

Aベストアンサー

お任せください!
そもそもscanfを使うというのはお勧めでは
ありません。scanfは文字+改行文字が入力
されないと完了しないためです。
が、それは良しとしましょう。
scanfの書式ですが、

int n = scanf("%[^\r\n]",buf);

という便利な書式があります。
perlでもおなじみの書式ですね。
上記の山文字"^"より前が読み込ませたい文字の集まりで、ハイフン指定が出来ます。
"^"より後ろが読込みを停止させたい文字の集まりです。上記の指定は復帰改行以外の文字が現れるまで読み込みます、という書式です。
下記のような指定も出来ます。

int n = scanf("%[a-zA-Z0-9\\: \t^\r\n]",buf);

なお、戻り値は読み込んだ項目数ですので、
if(n >= 1)
{
}
で判断できますね。


このカテゴリの人気Q&Aランキング

おすすめ情報