我想以“hostName:port”的形式将const char * hostName分隔为const char * hostNameFinal和数字端口。
我目前有以下代码:
const char* hostName = "localhost:643246";
long int port;
char hostNameChar[256];
sscanf(hostName, "%s:%d", hostNameChar, &port);
hostNameChar的输出是:localhost:643246 端口的输出是一个疯狂的数字,但不是643246
有时端口的值太大,我应该使用哪种数据类型? 如何正确匹配hostName,我得到2个带有所需信息的变量?
答案 0 :(得分:4)
由于你的问题标题中有C ++,我建议不要使用char数组并使用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?
}
答案 1 :(得分:1)
sscanf
的 %s
会读到下一个空格字符;它不知道要找一个冒号。因此,首先使用:
在hostName
中找到strchr
,然后使用sscanf
(或者,更好的是atoi
之类的内容)来解析端口数。 unsigned int
或任何类型的long
对于您在任何平台上的端口号都足够长; int
除了带有16位整数的小嵌入式东西(其中顶部位设置的端口号将变成负数,你可能不想要的东西)之外的任何东西都足够长。
(643246不是合法的端口号;端口号只有16位。范围从0到65535.)
编辑添加一些实际代码,以防我不明白我的建议:
const char * colon = strchr(hostName, ':');
memcpy(hostNameChar, hostName, colon-hostName);
hostNameChar[colon-hostName];
port = atoi(colon+1);
再次编辑,以确认Mark Loeser正确观察到atoi
没有进行任何错误检查。为了使上面的代码生产有价值,你应该(1)检查来自strchr
的返回值,以便在字符串中没有冒号时不会失败,(2)再次检查它以便在没有时失败冒号,但它超过256个字符(或动态分配hostNameChar
或其他东西),(3)使用strtol
而不是atoi
,(4)检查{{1的返回值确保端口号是合法的,并且(5)检查来自strtol
的其他 kinda-return-value,以确保端口号后没有尾随垃圾。但是,上面的代码应该给出一般的想法。
答案 2 :(得分:1)
试试这个:
#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);
}
这是因为%s会扫描一个单词。单词由空格分隔 %[&lt; BLA&gt;]匹配包含字符&lt; BLA&gt;的字符串。除非第一个字符是^。在这种情况下,它匹配字符不是&lt; BLA&gt;。
的字符串答案 3 :(得分:0)
您可以使用UrlGetPart http://msdn.microsoft.com/en-us/library/bb773781(v=VS.85).aspx
如果缓冲区太小,则返回E_POINTER,并且pcchOut指向的值将设置为缓冲区必须能够包含的最小字符数,包括终止NULL字符。
答案 4 :(得分:0)
另一种C ++解决方案(与C语言相比可怕:)
#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;
}
答案 5 :(得分:-1)
试试这个:
sscanf(hostName, "%s:%ld", hostNameChar, &port);
ld = long signed int
但是,我认为端口号不能是&gt; 65536