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
精彩评论