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 ステートメントは何も出力しません。長さ 0 のトークン一致に対して cout が返すこの文字は何ですか? 「\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関数は、指定された文字で区切られた指定された文字列の部分文字列を返します。IMO (テスト対象) 文字列に区切り文字のみが含まれている場合、strtok関数はNULL最初の呼び出しで返されます (これ以上のトークンはありません)。

さらに、コード スニペットでは、文字列を初期化されていないポインターにコピーします。strcpyへの呼び出しを、strdupコピーする前に割り当てられる基礎となるメモリの への呼び出しに置き換えます。編集:私が答えていたので、あなたはあなたの質問を修正しました

于 2013-09-24T09:43:54.070 に答える
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 関数呼び出しに対して。

次に、次のようにポイント変数にメモリを割り当てる必要があります

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