基于TDD开发一个判断字符串是否是IP4地址的功能
软件工程的一次作业,拿C++写的
目标问题:
1.基于TDD开发一个判断字符串是否是IP4地址的功能
2.使用任何OO语言
3.使用xUnit测试框架
目标列表:
1.有一个函数,函数中字符串承接输入
2.读取字符串
3.判断是否是Ip4
4.输出结果
测试框架:Gtest(基于xUnit架构的C++测试框架)
测试平台:Visual Studio 2019
使用语言:C++
1.创建一个字符串
目标列表:
1.有一个函数,函数中字符串承接输入
2.读取字符串
3.判断是否是Ip4
4.输出结果
从最简单的开始,首先创建一个字符串,然后让函数返回这个字符串
string JudgeIP()
{
string IP = "A";
return IP;
}
配置测试环境
#include <gtest/gtest.h>
#include <string>
using namespace std;
string JudgeIP()
{
string IP = "A";
return IP;
}
TEST(testCase, renturnIP)
{
EXPECT_EQ("A", JudgeIP());
}
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
开始测试,成功通过
2.从输入中读取字符串
目标列表:
1.有一个函数,函数中字符串承接输入
2.读取字符串
3.判断是否是Ip4
4.输出结果
现在函数已经有了空间存取字符串,接下来要从输入中读取字符串并返回这个字符串。修改后的代码如下:
string JudgeIP()
{
string IP = "A";
cin >> IP;
return IP;
}
因为输入改变,所以稍微修改一下测试环境
#include <gtest/gtest.h>
#include <string>
using namespace std;
string JudgeIP()
{
string IP = "A";
cin >> IP;
return IP;
}
TEST(testCase, renturnIP)
{
EXPECT_EQ("225.225.225.0", JudgeIP());
}
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
进行测试,输入了225.225.225.0,测试通过。
3.判断是否是IP4地址
目标列表:
1.有一个函数,函数中字符串承接输入
2.读取字符串
3.判断是否是Ip4
3.1 判断输入位数是否符合地址规范(7-15位之间)
3.2 判断.
的个数是否符合规范(3个)
3.3 判断由点分割出的字符是否都是数字
3.4 判断分割出的数字的范围是否在0-255之间
4.输出结果
3.1 判断输入位数是否符合地址规范(7-15位之间)
目标列表:
3.1 判断输入位数是否符合地址规范(7-15位之间)
3.2 判断.
的个数是否符合规范(3个)
3.3 判断由点分割出的字符是否都是数字
3.4 判断分割出的数字的范围是否在0-255之间
C++的string
类中有size()
这个函数可以返回字符串中字符的个数,略作修改,代码如下:
bool JudgeIP()
{
string IP = "A";
cin >> IP;
if (IP.size() > 15 || IP.size() < 7) {
return false;
}
return true;
}
再添加一个测试,测试块代码如下:
TEST(testCase, renturnIP)
{
EXPECT_EQ(false, JudgeIP());
EXPECT_EQ(true, JudgeIP());
EXPECT_EQ(true, JudgeIP());
}
测试输入为0.0
,255.255.255.255
,0.0.0.0
。测试结果如下,测试通过
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ruX87ZG2-1654611116127)(C:\Users\25087\AppData\Roaming\Typora\typora-user-images\image-20220607152155348.png)]
3.2判断.
的个数是否符合规范(3个)
目标列表:
3.1 判断输入位数是否符合地址规范(7-15位之间)
3.2 判断.
的个数是否符合规范(3个)
3.3 判断由点分割出的字符是否都是数字
3.4 判断分割出的数字的范围是否在0-255之间
创建一个新的变量dotCount
计数.
的个数,对IP
计数完成后,若dotCount
不为3,返回false
。修改后的代码如下:
bool JudgeIP()
{
string IP = "A";
int dotCount = 0;
cin >> IP;
if (IP.size() > 15 || IP.size() < 7) {
return false;
}
for (auto a : IP) {
if (a == '.') {
dotCount++;
}
}
if (dotCount != 3) {
return false;
}
return true;
}
其余代码不变,测试用例为0.0
,1.1.1.1
,233.33.333.3
。测试结果如下,测试通过
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ly8CLcbc-1654611116127)(C:\Users\25087\AppData\Roaming\Typora\typora-user-images\image-20220607153215131.png)]
3.3 判断由点分割出的字符是否都是数字
目标列表:
3.1 判断输入位数是否符合地址规范(7-15位之间)
3.2 判断.
的个数是否符合规范(3个)
3.3 判断由点分割出的字符是否都是数字
3.4 判断分割出的数字的范围是否在0-255之间
C++中有函数isdigit(int c)
可以判别字符是否是0-9的数字,新建一个变量temp
用于存储切分后的字符,每次判断后将temp
置空。新增的代码如下:
...
for (int i = 0;i < IP.size();i++)
{
if (IP[i] != '.')
{
temp += IP[i];
}
if (IP[i] == '.' || i == IP.size() - 1)
{
if (temp.size() == 0 || temp.size() > 3)
return false;
for (int j = 0; j < temp.size(); j++)
{
if (!isdigit(temp[j]))
return false;
}
temp = "";
}
}
...
测试部分代码修改如下:
TEST(testCase, renturnIP)
{
EXPECT_EQ(false, JudgeIP());
EXPECT_EQ(true, JudgeIP());
EXPECT_EQ(false, JudgeIP());
}
测试用例为a.a.a.a
,2.1.2.3
,1.A.3.a
。测试结果如下,测试通过。
3.4 判断分割出的数字的范围是否在0-255之间
目标列表:
3.1 判断输入位数是否符合地址规范(7-15位之间)
3.2 判断.
的个数是否符合规范(3个)
3.3 判断由点分割出的字符是否都是数字
3.4 判断分割出的数字的范围是否在0-255之间
C++中的函数stoi(string s)
可以将字符串转换成int
型变量,使用atoi
进行转换后判断。新增的代码如下:
...
int tempInt = stoi(temp);
if (tempInt > 255 || tempInt < 0)
{
return false;
}
...
其余部分代码不变,测试用例为0.0.1.256
,255.255.255.0
,-1.255.0.1
。测试结果如下,测试通过。
4.输出结果
目标列表:
1.有一个函数,函数中字符串承接输入
2.读取字符串
3.判断是否是Ip4
4.输出结果
使用cout
命令在控制台输出结果,在return false
前输入如下代码cout<<"输入的字符串不是IP4地址"<<endl;
在return true
前输入如下代码cout<<"输入的字符串是IP4地址"<<endl;
即可。
其余代码不做修改,测试用例为ajkhfkaduf
,255.255.0.255
,1.a.w.a
。测试结果如下,测试通过。
附录 完整工程代码
#include <gtest/gtest.h>
#include <string>
using namespace std;
bool JudgeIP()
{
string IP = "A";
string temp;
int dotCount = 0;
cin >> IP;
if (IP.size() > 15 || IP.size() < 7)
{
cout << "输入的字符串不是IP4地址" << endl;
return false;
}
for (auto a : IP)
{
if (a == '.')
{
dotCount++;
}
}
if (dotCount != 3)
{
cout << "输入的字符串不是IP4地址" << endl;
return false;
}
for (int i = 0;i < IP.size();i++)
{
if (IP[i] != '.')
{
temp += IP[i];
}
if (IP[i] == '.' || i == IP.size() - 1)
{
if (temp.size() == 0 || temp.size() > 3)
{
cout << "输入的字符串不是IP4地址" << endl;
return false;
}
for (int j = 0; j < temp.size(); j++)
{
if (!isdigit(temp[j])) {
cout << "输入的字符串不是IP4地址" << endl;
return false;
}
}
int tempInt = stoi(temp);
if (tempInt > 255 || tempInt < 0)
{
cout << "输入的字符串不是IP4地址" << endl;
return false;
}
temp = "";
}
}
cout << "输入的字符串是IP4地址" << endl;
return true;
}
TEST(testCase, renturnIP)
{
EXPECT_EQ(false, JudgeIP());
EXPECT_EQ(true, JudgeIP());
EXPECT_EQ(false, JudgeIP());
}
int main(int argc, char** argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}