2013-09-24 3 views
1

У меня есть следующий фрагмент кода C++:Значение, возвращаемое strtok() для токенов длины 0?

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», но не работает. Пожалуйста помоги.

EDIT: Комплексная программа для 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 для ввода: ...

+0

Google для «таНос», вам нужно выделить память для указателя. (и написано «кусок» кода, а не мир). –

+0

Я спешил. Его кусок сейчас. Выделенный Mem. Но все равно? – Madeyedexter

+0

Кстати, я думал, что ваш код был C, если это C++, вы должны использовать новый. –

ответ

2

Ваш код неопределенное поведение, вы не выделять память для points, доступ к нему вызывает UB.

Обновление, я мог бы написать validateIP, используя функции string и STL, только если бы мог. Mix 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; 
} 
+0

ОК, теперь я сделал это, так что еще, что strtok() возвращает для токенов длины 0 – Madeyedexter

+0

вот полный код. – Madeyedexter

1

strtok функция возвращает подстроку заданной строки, ограниченной данного символа. IMO (для тестирования), если ваша строка содержит только ограничивающие символы, функция strtok вернет NULL (не больше токенов) при первом вызове.

Кроме того, в фрагменте кода вы копируете строку в неинициализированный указатель. Замените ваш вызов на strcpy вызовом strdup для выделения основной памяти перед копированием. Edit: вы изменили свой вопрос, как я отвечал

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); 
} 
+0

Не забудьте бесплатно ;-) –

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]; 
Смежные вопросы