초보자인데 질문하나만 드립니다. ^^;; stl map 호출이 안되서요.

balgarac1의 이미지

우선 명령어와 명령어 처리 함수를 map에 저장해 놓았습니다. 
#ifndef _COMMNAD_HANDLER_H_
#define _COMMAND_HANDLER_H_
 
 
#include <iostream>
#include <map>
#include "ThreadClient.h"
#include "user.h"
 
using namespace std;
 
class commandHandler
{
 
	private:
 
 
		 char cmd[20];
		 char sendBuff[BUFSIZ];
		 typedef void (commandHandler::*cmdHandler)(User &); // 멤버 함수 포인터를 사용했습니다.
 
 
	public:
 
		 commandHandler();
		 ~commandHandler();
 
		 void cmdAppend();
		 void who(User&);
		 void quit(User&);
		 void user(User&);
		 void talk(User&);
		 void help(User&);
		 void debug(User&);
 
		 map<char *, cmdHandler> cmdHandlerMap;
		 pair<map<char *, cmdHandler>::iterator, bool> mpair;
 
 
};
 
#endif
 
 
 
 
#----- commandHandler.cpp -----#
////////////////////////////////
 
 
 
아래와 같이 생성자를 호출하면서 map에 insert를 시켰습니다.
 
 
 
#include "commandHandler.h"
 
char *Usage[] = { "User <My ID>\n", "who\n", "talk <your ID> message start \n", "quit\n", "help\n", "debug\n", ". end of talk\n" };
 
commandHandler::commandHandler()
{
 
	// constructor
	cmdAppend();
 
}
 
commandHandler::~commandHandler()
{
 
	// destructor
 
	cmdHandlerMap.clear(); // Map clear.
 
}
void commandHandler::cmdAppend()
{
 
	mpair = cmdHandlerMap.insert(pair<char *, cmdHandler>("who", &commandHandler::who));
	if (mpair.second == true)
		cout << "save complete." << endl;
	else
		cout << "save failed." << endl;
 
	cmdHandlerMap.insert(pair<char *, cmdHandler>("user", &commandHandler::user));
	cmdHandlerMap.insert(pair<char *, cmdHandler>("talk", &commandHandler::talk));
	cmdHandlerMap.insert(pair<char *, cmdHandler>("quit", &commandHandler::quit));
	cmdHandlerMap.insert(pair<char *, cmdHandler>("help", &commandHandler::help));
	cmdHandlerMap.insert(pair<char *, cmdHandler>("debug", &commandHandler::debug));
 
 
}
void commandHandler::who(User &userInfo)
{
 
	sprintf(sendBuff, "%s \r\n\r\n", "who");
	send(userInfo.sock, sendBuff, strlen(sendBuff) + 2, 0);
	cout << "send ok" << endl;
 
 
}
 
void commandHandler::user(User &userInfo)
{
 
	cout << "#-----USER-----#" << endl;
 
	cout << "Input Your ID:"; cin >> userInfo.ID;
	sprintf(sendBuff, "%s %s \r\n\r\n", "user", userInfo.ID);
	send(userInfo.sock, sendBuff, strlen(sendBuff) + 2, 0);
	cout << "send ok" << endl;
 
}
 
 
 
 
 
#-----THREADCLIENT_HEADER-----#
///////////////////////////////
 
 
 
 
#ifndef __THREAD_CLIENT_H__
#define __THREAD_CLIENT_H__
 
 
#include <iostream>
#include <process.h>
#include <WinSock2.h>
#include "user.h"
 
#define BUFLEN 256
#pragma warning(disable:4996)
 
using namespace std;
 
 
class ThreadClient
{
 
 
	private:
 
 
		SOCKET servSock;
		WSADATA wsaData;
		SOCKADDR_IN servAddr;
		HANDLE hThread[2];
		commandHandler *cmdHandler; // 명령어 처리 함수를 호출할 수 있도록 commandHandler 포인터를 멤버 변수로 놓았습니다.
		User userData;
 
 
	public:
 
 
		ThreadClient();
		~ThreadClient();
 
		void socketInit();
		void socketStart();
		void socketEnd();
		void ErrorHandling(char *);
 
 
};
 
 
unsigned WINAPI send_Msg(void * arg);
unsigned WINAPI recv_Msg(void * arg);
 
#endif
 
 
 
 
 
#-----THREADCLIENT.CPP-----#
////////////////////////////
 
 
 
 
 
#include "ThreadClient.h"
#include "commandHandler.h"
#include "user.h"
 
HANDLE hMutex;
typedef void(commandHandler::*cmdHandler)(User&);
static map<char *, cmdHandler>::iterator iter; // 반복자가 필요한데 전역변수 이외에는 딱히 불러다가 쓸 수 있는 방법이 없어보여서 전역으로 선언했습니다.
 
ThreadClient::ThreadClient()
{
 
 
	//constructor
	cmdHandler = new commandHandler(); // commandHandler 객체를 동적할당합니다.
 
 
}
 
void ThreadClient::socketStart()
{
 
	servSock = socket(PF_INET, SOCK_STREAM, 0);
	if (servSock == INVALID_SOCKET)
	{
 
		ErrorHandling("socket()");
 
	}
 
	memset(&servAddr, 0, sizeof(servAddr));
	servAddr.sin_family = AF_INET;
	servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	servAddr.sin_port = htons(9190);
 
	if (connect(servSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
	{
 
		ErrorHandling("connect()");
 
	}
 
 
		userData.sock = servSock; // 소켓 핸들 값을 저장하고,
		userData.cmdHand = cmdHandler; // 핸들러의 객체 주소를 저장해서 쓰레드의 데이터로 넘깁니다.
 
		hThread[0] = (HANDLE)_beginthreadex(NULL, 0, send_Msg, (void *)&userData, 0, NULL); // 쓰레드를 호출합니다.
		hThread[1] = (HANDLE)_beginthreadex(NULL, 0, recv_Msg, (void *)&userData, 0, NULL);
 
		WaitForMultipleObjects(2, hThread, FALSE, INFINITE);
 
}
 
 
 
 
 
unsigned WINAPI send_Msg(void * arg)
{
 
	User *userInfo = (User *)arg;
	char Buff[BUFSIZ];
	// char sendBuff[BUFSIZ];
	char userComm[25];
 
 
	WaitForSingleObject(hMutex, INFINITE);
	while (true)
	{
 
 
		memset(Buff, 0, sizeof(Buff));
		memset(userComm, 0, sizeof(userComm));
 
		//cout << "Input Msg:"; 
		cin.getline(Buff, BUFLEN); // 유저에게 입력을 받아서 
 
 
		sscanf(Buff, "%s", userComm); // 명령어 부분만을 파싱한 뒤.
 
		iter = userInfo->cmdHand->cmdHandlerMap.find(userComm);//맵의 키값을 찾아서 value를 호출 but,호출실패,왜그런건가요?
		if (iter != userInfo->cmdHand->cmdHandlerMap.end())
			iter->second; // void commandHandler::user(User &userInfo) user를 입력했으면 이 함수가 호출되야하는데요..
                                         호출이 안됩니다..
                                         User 정보를 인자로 넘기지 않아서 그런것일수도 있나요?만약그렇다면 어떻게 넘겨야 하나요?
 
 
	}
 
	ReleaseMutex(hMutex);
	return 0;
}

가르침 부탁드려용ㅇ^^;;

jick의 이미지

자세히 읽어본 건 아니지만, iter->second 대신에 iter->second(인자) 형태로 써야 할 것 같은데요?

f가 함수 포인터일 때 그냥 f라고만 쓰면 아무 일도 일어나지 않습니다.

* 그리고 99%의 확률로 "statement has no effect" 같은 경고가 있어야 할 것 같은데 컴파일할 때 -Wall 주고 하셨는지...

balgarac1의 이미지

iter->second(인자) 이런 형태로 해보았는데 여전히 컴파일 오류가 나네요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.