1

我有以下一段 C++ 代码:

string dots="...";
char *points=(char *)malloc(sizeof(char)*20);
strcpy(points,dots.c_str());
points=strtok(points,".");
while(points!=NULL)
{
cout<<points<<endl;
points=strtok(NULL,".");
}

cout 语句不打印任何内容。cout 为 0 长度标记匹配返回的这个字符是什么?我试图检查 '\0' 但不起作用。请帮忙。

编辑:验证 IP 地址的完整程序

#include<iostream>
#include<cstring>
#include<stdlib.h>
using namespace std;

int validateIP(string);
int main()
{
string IP;
cin>>IP;
int result=validateIP(IP);
if(result==0)
    cout<<"Invalid IP"<<endl;
if(result==1)
    cout<<"Valid IP"<<endl;
return 0;
}
//function definition validateIP(string)
int validateIP(string IP)
{
char ip[16];
int dotCount=0;
strcpy(ip,IP.c_str());
//check number of dots
for(int i=0;i<strlen(ip);++i)
{
    if(ip[i]=='.')
        {
            dotCount++;
        }
}
if(dotCount!=3)
    return 0;
//check range
char *numToken;
numToken = strtok (ip,".");
while (numToken!= NULL)
{
    int number;
    if(numToken!=NULL)          //check for token of length 0(e.g. case: ...)                                    
    number=atoi(numToken);      //i also checked for (numToken[0]!='\O')
    else return 0;
    if(number<0 or number>255)
        return 0;
    numToken=strtok (NULL,".");
}
return 1;
}

程序打印 ValidIP 以供输入: ...

4

4 回答 4

2

您的代码具有未定义的行为,您没有为 分配内存points,访问它会调用 UB。

validateIP更新,如果可以的话,我可能会使用字符串和 STL 函数来编写。混合 C/C++ 不利于维护。

#include <sstream>

int to_int(const std::string& s)
{
  int i(0);
  std::stringstream ss(s);  
  ss >> i;     

  return i;
}

bool isValidIp(const std::string& IP)
{    
   if (std::count(IP.begin(), IP.end(), '.') != 3)
   {
      return false;
   }

   std:stringstream ss(IP);

   int token;
   std::string s;

   while(std::getline(ss, s, '.'))
   {
     int token = to_int(s);
     if (token < 0 || token > 255)
     {
       return false;
     }
   }
   return true;
 }

然后你叫它:

 if (isValidIp(IP))
 {
     std::cout << "Valid IP" << std::endl;
 }
 else
 {
     std::cout << "Invalid IP" << std::endl;
 }
于 2013-09-24T09:33:08.033 回答
1

strtok 用于标记字符串。说,我有一个字符串“abc.def.ghi.jkl”,然后我们可以使用 strtok 来获取分隔符上的标记。

  char a[]="abc.def.ghi.jkl";
  char tmp=strtok(a, ".");
  if (tmp != NULL)   //Required because strtok will return null if it failes find the delimiter
     printf("\n value is [%s]", tmp); //out put is abc

所以,在你的情况下,“...”是字符串和“。” 是导致空字符串的分隔符,因为第一个字符和分隔符 '.' 之间没有字符。

您的代码将返回空字符串说“”作为输出。对于所有 sttok 函数调用。

其次,您必须为 points 变量分配内存,例如

 char points[dots.length()+1];
于 2013-09-24T09:50:28.933 回答
1

strtok函数返回由给定字符分隔的给定字符串的子字符串。IMO(待测试)如果您的字符串仅包含定界字符,则该strtok函数将NULL在第一次调用时返回(不再有标记)。

此外,在您的代码片段中,您将字符串复制到未初始化的指针。将调用替换strcpy为调用以strdup在复制之前分配底层内存。编辑:您在我回答时修改了您的问题

于 2013-09-24T09:43:54.070 回答
1

如果字符串只包含分隔字符,则strok返回NULL

你可能想要这个:

int main()
{
  string dots=". . ."; //Notice space
  char *points=(char *)malloc(sizeof(char)*20);
  char *p; // Use a char pointer
  strcpy(points,dots.c_str());
  p=strtok(points,".");
  while(p!=NULL)
 {
   cout<<points<<endl;
   p=strtok(NULL,".");
  }
 /* Free Memory */
 free(points);
}
于 2013-09-24T09:44:32.323 回答