strtok()为长度为0的标记返回的值?

时间:2013-09-24 09:31:45

标签: c++ string strtok

我有以下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 个答案:

答案 0 :(得分:2)

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

更新,我可能只在可能的情况下使用字符串和STL函数编写validateIP。混合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;
 }

答案 1 :(得分:1)

strtok函数返回给定字符分隔的给定字符串的子字符串。 IMO(待测试)如果您的字符串只包含分隔字符,strtok函数将在第一次调用时返回NULL(不再有令牌)。

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

答案 2 :(得分: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);
}

答案 3 :(得分:1)

strtok用于标记字符串。说,我有一个字符串&#34; abc.def.ghi.jkl&#34;然后我们可以使用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

所以,在你的情况下&#34; ...&#34;是字符串和&#39;。&#39;是分隔符,它导致空字符串,因为第一个字符和分隔符之间没有字符。&#39;

你的代码将返回空字符串说&#34;&#34;作为输出。对于所有sttok函数调用。

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

 char points[dots.length()+1];