2013-06-26 27 views
0

我非常喜歡%s,ID的概念。我注意到這與char有效,我知道這是一個C風格的特性。我在想,如果那裏有任何其他方式來實現%s的字符串:%s不會使用字符串

繼承人我的代碼:

#include "services.h" 

#include <iostream> 
using namespace std; 

services::services() 
{ 
} 


services::~services() 
{ 
} 

int services::startup() 
{ 

#if defined(WINDOWS) 
    { 
     WSAData data; 

     if(WSAStartup(MAKEWORD(2,2), &data) != 0) 
      exit(1); 
    } 
#endif 

    int addresssize = sizeof(address); 

    address.sin_addr.s_addr = inet_addr("69.60.118.163"); 
    address.sin_family = AF_INET; 
    address.sin_port = htons(6667); 

    sock = socket(AF_INET,SOCK_STREAM,0); 

    if(sock < 0) 
     return -1; 

    string PASSWORD = "password1"; 
    string SERVER_NAME = "admin.services.net"; 
    string SERVER_DESC = "Administration IRC Services"; 


    if(connect(sock,(struct sockaddr *)&address,addresssize) == 0) 
    { 
     send_cmd("PASS ","%s\n",PASSWORD); 
     send_cmd("SERVER ","%s 1 %s\n",SERVER_NAME,SERVER_DESC); 

    return 0; 
    } 

    return -1; //ooops 
} 

void services::parseData() 
{ 
    char buffer[512]; 
    stringstream convert; 
    string newbuffer; 
    for(;;) 
    { 
     int index = recv(sock,buffer,512-1,0); 
     buffer[index]='\0'; 
     newbuffer = buffer; 

     cout << newbuffer.c_str() << endl; 

     if(index == 0) 
     { 
      cout << "Connection was closed!" << endl; 
      break; 
     } 

     system("pause"); 

    } 
} 

void services::send_cmd(string cmd) 
{ 



} 

void services::send_cmd(string cmd, string param,...) 
{ 
    int bufsize; 
    string newmsg; 

     newmsg = (cmd += param); 

     cout << newmsg.c_str() << endl; 

     bufsize = sizeof(newmsg); 

     send(sock,newmsg.c_str(),strlen(newmsg.c_str()),0); 
} 

現在的問題是send_cmd詮釋,他的啓動功能(在連接檢查)實際上是給出% s而不是密碼/服務器信息的值

它只是在控制檯中顯示爲「PASS%s」或「SERVER%s」 - 正如我所說我喜歡%s的概念是否有其他方式來實現這個,或者只是使用send_cmd("PASS",PASSWORD);代替(它工作正常,我只是挑剔)

+1

send_cmd( 「PASS」, 「%s的\ n」,PASSWORD.c_str()); –

+0

不要忘記send_cmd也發送一個字符串 – aeonicone

+1

將一個字符串(或任何其他非POD類類型的對象)作爲函數的一個變量參數傳遞給未定義的行爲。 –

回答

1

您可以使用sprintf將其轉換爲字符串,然後將send_cmd修改爲只有兩個參數。

+0

這就是另一個問題,我有更多的參數,它尋找 – aeonicone

5

這裏有幾種可能性。一是修改現有的功能一點,使用vsprintf中,因此它可以接受的參數任意數量和做替代像printf將:

void services::send_cmd(string cmd, char const *param,...) 
{ 
    char buffer[512]; 

    va_list args; 
    va_start(param, args); 
    vsprintf(buffer, args, param); 
    va_end(args); 
    cmd += buffer; 
    send(sock, cmd.c_str(),cmd.length(),0); 
} 

這股與所有功能以可變參數列表,雖然一個問題:將std::string(或任何其他非POD類類型的對象)作爲可變參數之一傳遞將導致未定義的行爲。

如果您希望能夠通過std::string s,您還有其他一些可能性。更簡單的方法是使用流將數據寫入套接字。爲此,你需要編寫一個(非常簡單的)流緩衝類來將數據寫入套接字,而不是像磁盤上的文件那樣更典型的目標。這不是很難做,但是當我甚至不確定你想要它時,發佈它肯定太多了。

第三種可能性是使用可變參數模板來支持各種類型的處理參數。這將消除必須傳遞格式字符串,因爲它可以直接從參數中推導出類型。 然而,再一次,當它完全不清楚它是你想要的還是關心的時候,可能會有點多。 其實,思考它,這是足夠短,我可能也僅僅包含它:

#include <sstream> 
#include <string> 
#include <iostream> 

template <class T> 
std::string stringify(T const &t) { 
    std::stringstream b; 
    b << t; 
    return b.str(); 
} 

template<typename T, typename... Args> 
std::string stringify(T arg, const Args&... args) { 
    return stringify(arg) + stringify(args...); 
} 

template<typename... Args> 
void send_cmd(const Args&... args) { 
    std::string buffer = stringify(args...); 
    send(sock, buffer.c_str(), buffer.length(), 0); 
} 

int main() { 
    std::string three{" three"}; 

    send_cmd("one: ", 1, " two: ", 2, three, "\n"); 

    return 0; 
} 

我度過了一些字符串常量,整型,並在演示代碼std::string,但本質上任何類型支持像cout << whatever應該工作正常。

相關問題