c 소스를 c++로 구현하는 방안에 대해서 질문드려요.

balgarac1의 이미지

유저에게 명령어 입력을 받으면 명령어 처리를 하는 로직 속에서

void openConnection(char * openCmd);
void nlist(char *nlistCmd);
void ls(char *lsCmd);
void get(char *getCmd);
void put(char *putCmd);
void cd(char *cdCmd);
void quit(char *quitCmd);
void pwd(char *pwdCmd);
void bye(char *byeCmd);
void help(char *helpCmd);
void debugSet(char *debugCmd);
 
typedef struct _FtpCmdHandler {
	char cmd[5];
	void (*handler)(char * arg);
	char * usage;
} FtpCmdHandler;
 
FtpCmdHandler ftpCmdHandler[] = {
		{CMD_OPEN, openConnection, "open <IP address>\t-- connect to FTP server"},
		{CMD_NLIST, nlist, "nlist\t -- name list"},
		{CMD_LS, ls, "ls\t -- directory list"},
		{CMD_GET, get, "get <filename>\t-- download the file"},
		{CMD_PUT, put, "put <filename>\t-- upload the file"},
		{CMD_PWD, pwd, "pwd\t-- print working directory"},
		{CMD_CD, cd, "cd\t-- change working directory"},
		{CMD_QUIT, quit, "quit\t-- close FTP session and exit"},
		{CMD_BYE, bye, "bye\t-- close FTP session and exit"},
		{CMD_HELP, help, "help\t-- print usage"},
		{CMD_DEBUG, debugSet, "debug\t-- print debug message"}
};
 
이런 식으로 구조체 안에 함수 포인터를 이용해
 
void commandHandle(char * cmd) {
	int i;
	int cmdNum;
	cmdNum = sizeof(ftpCmdHandler) / sizeof(FtpCmdHandler);
 
	for (i = 0; i < cmdNum; i++) {
		if (!strncmp(cmd, ftpCmdHandler[i].cmd, strlen(ftpCmdHandler[i].cmd))) {
			(*(ftpCmdHandler[i].handler))(cmd);
			break;
		}
	}
	if (i == cmdNum)
		printf("?Invalid command\n");
}

입력 받은 명령어 처리를 하는데요.
c++에서 이런 로직으로 구현해보고 싶은데 어떤 방법으로 구현할 수 있을까요??
힌트좀 주세요.

익명 사용자의 이미지

std::map을 쓰세요

익명 사용자의 이미지

map이면
key값은 명령어 문자열
value값은 함수 주소 값인데.. 그럼 용법을 나타내는 문자열 값은 포기해야 되나요??

익명 사용자의 이미지

commandhandler를 정의해서 value로 쓰면 되죠

익명 사용자의 이미지

typedef void (*cmdHandler)(void) <- value 값을 넣을 함수 포인터를 typedef로.

map cmdMap; <- map 객체 생성.

cmdMap.insert("who", this->who); <- 키 값으로 명렁어 "who" 넣고, 그에 따른 value를 함수 who를 저장하는 이런 식으로 코드가 작성되지 않나요? 용법은 어디에 들어갈 수 있죠??

void who(void)
{
..
}

kukyakya의 이미지

map을 이용하시려면, 실제로 컴파일해보진 않았지만 대충 컨셉을 다음과 같이 이용하시면 될 것 같습니다.

std::map<std::string,
         std::pair<void (*)(const std::string&), std::string> > handler;
 
handler[CMD_OPEN]  = std::make_pair(&openConnection, "open <IP address>\t-- connect to FTP server");
handler[CMD_NLIST] = std::make_pair(&nlist,          "nlist\t -- name list");
.
.
.
 
void commandHandle(const std::string& cmd) {
  const auto it = handler.find(cmd);
 
  if(it != handler.end()) {
    const auto& value = it->second;
 
    value.first(value.second);
  }
  else {
    std::cout << "?Invalid command" << std::endl;
  }