开发者

C++ string matching(hostname and port)

I want to seperate a const char* hostName in the form of "hostName:port" to a const char* hostNameFinal and a number port.

I have currently following code:

const char* hostName = "localhost:643246";

long int port;
char hostNameChar[256];
sscanf(hostName, "%s:%d", hostNameChar, &port);

The output of the hostNameChar is: localhost:643246 The output of port is a crazy number but开发者_开发知识库 not 643246

Sometimes the value of port is too big, which datatype should i use? How can I match the hostName correctly, that I get 2 variables with the needed info?


Since you have C++ in your question title, I would suggest steering clear of char arrays and using std::string.

#include <string>
#include <sstream>

std::string hostName = "localhost:643246";

size_t colonPos = hostName.find(':');

if(colonPos != std::string::npos)
{
     std::string hostPart = hostName.substr(0,colonPos);
     std::string portPart = hostName.substr(colonPos+1);

     std::stringstream parser(portPart);

     int port = 0;
     if( parser >> port )
     {
          // hostname in hostPart, port in port
          // could check port >= 0 and port < 65536 here
     }
     else
     {
         // port not convertible to an integer
     }
}
else
{
    // Missing port?
}


sscanf with %s will read up to the next whitespace character; it doesn't know to look for a colon. So, instead: First locate the : in hostName using strchr and only then use sscanf (or, better, something like atoi) to parse the port number. An unsigned int or any sort of long will be long enough for your port number on any platform; an int will be long enough on anything other than a little embedded thing with 16-bit integers (where port numbers with the top bit set will turn into negative numbers, which you probably don't want).

(643246 is not a legal port number; port numbers are only 16 bits. They range from 0 to 65535.)

EDITED to add some actual code in case it isn't clear what I'm suggesting:

const char * colon = strchr(hostName, ':');
memcpy(hostNameChar, hostName, colon-hostName);
hostNameChar[colon-hostName];
port = atoi(colon+1);

EDITED again to acknowledge Mark Loeser's correct observation that atoi doesn't do any error checking. To make the above code production-worthy you should (1) check the return value from strchr so as not to fail when there is no colon in the string, (2) check it again so as not to fail when there's a colon but it's further in than 256 characters (or allocate hostNameChar dynamically or something), (3) use strtol rather than atoi, (4) check the return value from strtol to make sure the port number is legal, and (5) check the other kinda-return-value from strtol to make sure there isn't trailing junk after the port number. The code above, however, should give the general idea.


Try this:

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

int main()
{
    const char* hostName = "localhost:643246";

    long int port;
    char hostNameChar[256];
    if (sscanf(hostName, "%[^:]:%d", hostNameChar, &port) != 2)
    {
        // It did not work.
        // scanf() returns the number of matched tokens.
        fprintf(stdout, "Fail\n");
        exit(1);
    }
    fprintf(stdout, "Host(%s) Port(%d)\n", hostNameChar, port);
}

This is because %s scans a word. Words are delimited by whitespace.
The %[<BLA>] matches a string that contains the characters <BLA>. Unless the first character is ^. In which case it matches the string where the characters are not <BLA>.


You can use UrlGetPart http://msdn.microsoft.com/en-us/library/bb773781(v=VS.85).aspx

If the buffer was too small, E_POINTER is returned, and the value pointed to by pcchOut will be set to the minimum number of characters that the buffer must be able to contain, including the terminating NULL character.


Another C++ solution (awful compared to the C one :)

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

using namespace std;

int main()
{
  const char* hostName = "localhost:643246";
  long int port;
  char hostNameChar[256];

  istringstream iss(hostName);
  string hostNameString;
  getline(iss, hostNameString, ':');
  strcpy(hostNameChar, hostNameString.c_str());
  iss >> port;
  cout << hostNameChar << "-" << port << endl;
}


Try this:

sscanf(hostName, "%s:%ld", hostNameChar, &port);

ld = long signed int

However, I think the port number cannot be > 65536

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜