C ++字符串匹配(主机名和端口)

时间:2011-03-22 17:11:55

标签: c++ string port match hostname

我想以“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个带有所需信息的变量?

6 个答案:

答案 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