您的位置:首页 > 移动开发 > Objective-C

(Foundation)NSObject 、 NSString 、 NSMutableString

2015-12-15 19:48 477 查看

1 重构Student和Book类

1.1 问题

本案例需要创建一个Book类,类中有一个整型price属性,用于记录书的价格。还需要创建一个Student类,类中有两个带参属性,它们是整型的年龄age和类Book类型的book,分别用于存储学生的年龄和学生正在学习的书,book属性带有copy参数,并且有一个study方法,用于显示年龄为age的学生学习价格为book.price的书。

在主程序中创建Student类的一个对象和Book类的两个对象,首先让Student类的对象拥有一个Book类的对象,然后让Student类的对象更换了拥有对象,换成另一个Book类对象。

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义类Book

首先,在Day01工程中新添加Book.h文件,用于定义新的类Book。

代码如下所示:

#import <Foundation/Foundation.h>

@interface Book : NSObject<NSCopying>

@property int price;

@end

在上述代码中,以下代码:

@interface Book : NSObject<NSCopying>

定义了类Book,该类采用了NSCopying协议。

在上述代码中,以下代码:

@property int price;

在Book类中定义了一个属性,是整型变量price,用于存储书的价格。

然后,在类Book的实现部分,即在Book.m文件中,添加两个方法的实现,一个是copyWithZone方法,该方法是在NSCopying协议中声明的方法,用于深拷贝;另一个是dealloc方法,由于使用ARC,该方法在本类中实际上没有任何实际意义,只是在类的对象销毁时,在控制台上输出一个提示。

代码如下所示:

#import "Book.h"

@implementation Book

-(id)copyWithZone:(NSZone*)zone

{

Book* book = [[Book allocWithZone:zone] init];

book.price = self.price;

return book;

}

-(void)dealloc{

NSLog(@"书对象销毁了 price:%d",self.price);

}

@end

上述代码中,copyWithZone方法不能在类外直接被调用,它是在向一个对象发送copy消息时,由copy消息调用。在该方法中,以下代码:

Book* book = [[Book allocWithZone:zone] init];

book.price = self.price;

生成一个本类对象的副本。需要注意的是分配空间使用的是allocWithZone方法。

上述代码中,dealloc方法也不能在类外直接被调用,它是在一个对象被release并且对象的引用计数为0时,由内存管理程序调用的方法。

步骤二:定义类Student

首先,在Day01工程中新添加Student.h文件,用于定义新的类Student。

代码如下所示:

#import <Foundation/Foundation.h>

#import "Book.h"

@interface Student : NSObject

{

}

@property(nonatomic,assign) int age;

@property(nonatomic,copy) Book* book;

-(void)study;

@end

在上述代码中,定义了类Student,在类中有两个带参属性。

一个属性是整型变量age,如下代码所示:

@property(nonatomic,assign) int age;

用于存储学生的年龄。它有两个参数,一个是nonatomic,它代表对属性赋值的时候不加锁,即在多线程环境下访问时可能会出现数据错误,如果需要在多线程环境下运行,为保证数据不会出现错误,可使用atomic参数,它会在对属性赋值的时候加锁。另一个参数是assign,对于C语言的基本数据类型,只能选取这个参数。

另一个属性是book,如下代码所示:

@property(nonatomic,copy) Book* book;

用于存储学生正在学习的书。它有两个参数,一个是nonatomic,另一个参数是copy,该参数一般用于NSObject类及其子类的对象,这些对象在赋值时实现深拷贝,即属性book指向的对象是赋值给它的对象的副本。

然后,在类Student的实现部分,即在Student.m文件中,添加dealloc方法和study方法的实现。

代码如下所示:

#import "Student.h"

@implementation Student

-(void)dealloc{

//将所有引用类型的属性在此释放掉

NSLog(@"学生对象销毁了,dealloc方法执行了");

}

-(void)study{

NSLog(@"学生 age:%d 学习书 price:%d 中的知识",self.age,self.book.price);

}

@end

由于使用ARC,dealloc方法在本类中实际上没有任何实际意义,只是在类的对象销毁时,在控制台上输出一个提示。

study方法要完成的工作是在控制台上输出学生的年龄和正在学习的书。

步骤三:在主程序中使用Student类和Book类

代码如下所示:

#import <Foundation/Foundation.h>

#import "Student.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

Student* stu1 = [[Student alloc]init];

stu1.age = 18;

Book* sanguo = [[Book alloc]init];

sanguo.price = 10;

stu1.book = sanguo;//将书对象给学生对象

Book* hongloumeng = [[Book alloc]init];

hongloumeng.price = 20;

stu1.book = hongloumeng;

[stu1 study];

}

return 0;

}

在上述代码中,以下代码:

Student* stu1 = [[Student alloc]init];

stu1.age = 18;

定义了一个Student类的对象stu1,并将stu1的age属性赋值为18。

在上述代码中,以下代码:

Book* sanguo = [[Book alloc]init];

sanguo.price = 10;

stu1.book = sanguo;//将书对象给学生对象

首先,定义了一个Book类的对象sanguo,并将sanguo的price属性赋值为10。然后,将stu1的book属性赋值为sanguo。我们知道book属性有一个参数是copy,它会将赋值给它的sanguo对象生成一个副本,将副本赋值给stu1.book,这样指针sanguo和指针stu1.book将分别指向两个不同的地址,即实现深拷贝的功能。

在上述代码中,以下代码:

Book* hongloumeng = [[Book alloc]init];

hongloumeng.price = 20;

stu1.book = hongloumeng;

首先,定义了一个Book类的对象hongloumeng,并将hongloumeng的price属性赋值为20。然后,将stu1的book属性重新赋值为hongloumeng。我们知道book属性有一个参数是copy,它会将赋值给它的hongloumeng对象生成一个副本,将副本赋值给stu1.book。但在赋值前stu1.book中存有sanguo的副本对象,此时将hongloumeng的副本对象赋值给它会造成sanguo副本的丢失,为了防止这一情况的发生,ARC将自动插入代码,向sanguo副本对象发送release消息,在本案例中,由于sanguo副本对象的引用计数值为1,所以向其发送release消息后,sanguo副本对象将被释放。

在上述代码中,以下代码:

[stu1 study];

是向对象stu1发送study消息时,因为hongloumeng的引用计数为1,所以它能显示出hongloumeng的价格。

1.3 完整代码

本案例中,类Book声明,即Book.h文件,完整代码如下所示:

#import <Foundation/Foundation.h>

@interface Book : NSObject<NSCopying>

@property int price;

@end

类Book实现,即Book.m文件,完整代码如下所示:

#import "Book.h"

@implementation Book

-(id)copyWithZone:(NSZone*)zone

{

Book* book = [[Book allocWithZone:zone] init];

book.price = self.price;

return book;

}

-(void)dealloc{

NSLog(@"书对象销毁了 price:%d",self.price);

}

@end

本案例中,类Student声明,即Student.h文件,完整代码如下所示:

#import <Foundation/Foundation.h>

#import "Book.h"

@interface Student : NSObject

{

}

@property(nonatomic,assign) int age;

@property(nonatomic,copy) Book* book;

-(void)study;

@end

类Student实现,即Student.m文件,完整代码如下所示:

#import "Student.h"

@implementation Student

-(void)dealloc{

//将所有引用类型的属性在此释放掉

NSLog(@"学生对象销毁了,dealloc方法执行了");

}

-(void)study{

NSLog(@"学生 age:%d 学习书 price:%d 中的知识",self.age,self.book.price);

}

@end

主程序,即main.m,完整代码如下所示:

#import <Foundation/Foundation.h>

#import "Student.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

Student* stu1 = [[Student alloc]init];

stu1.age = 18;

Book* sanguo = [[Book alloc]init];

sanguo.price = 10;

stu1.book = sanguo;//将书对象给学生对象

Book* hongloumeng = [[Book alloc]init];

hongloumeng.price = 20;

stu1.book = hongloumeng;

[stu1 study];

}

return 0;

}

2 重构Student类

2.1 问题

使用深拷贝的概念重构Student类,在类中包含以下实例变量int age、char gender、double salary信息,定义一个方法printInfo输出所有实例变量的值,在主函数中对Student类的对象进行赋值并输出。

2.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:定义类Student

由于是对Student类的重构,所以在Day01-2工程中新添加Student.h文件用于定义新的类Student。

代码如下所示:

#import <Foundation/Foundation.h>

@interface Student : NSObject<NSCopying>

{

}

@property int age;

@property char gender;

@property double salary;

-(void)printInfo;

@end

上述代码中,以下代码:

@interface Student : NSObject<NSCopying>

定义了类Student,该类采用了NSCopying协议。

在上述代码中,以下代码:

@property int age;

@property char gender;

@property double salary;

在Student类中定义了三个属性,一个是整型变量age,用于存储学生的年龄,另一个是字符型变量gender,用于存储学生的性别,最后一个是双精度浮点型变量salary,用于存储学生的津贴。

上述代码中,以下代码:

-(void)printInfo;

定义了类Student的一个方法printInfo,用于在控制台上输出三个属性的值。

然后,在类Student的实现部分,即在Student.m文件中,添加两个方法的实现,一个是copyWithZone方法,该方法是在NSCopying协议中声明的方法,用于深拷贝;另一个是printInfo方法。

代码如下所示:

#import "Student.h"

@implementation Student

-(id)copyWithZone:(NSZone *)zone

{

Student *stu = [[Student allocWithZone:zone] init];

stu.age = self.age;

stu.gender = self.gender;

stu.salary = self.salary;

return stu;

}

-(void)printInfo

{

NSLog(@"age=%d", _age);

NSLog(@"gender=%c", _gender);

NSLog(@"salary=%lf", _salary);

}

@end

上述代码中,copyWithZone方法不能在类外直接被调用,它是在向一个对象发送copy消息时,由copy消息调用。在该方法中,以下代码:

Student *stu = [[Student allocWithZone:zone] init];

stu.age = self.age;

stu.gender = self.gender;

stu.salary = self.salary;

生成一个本类对象的副本。需要注意的是分配空间使用的是allocWithZone方法。

步骤二:在主程序中使用Student类

代码如下所示:

#import <Foundation/Foundation.h>

#import "Student.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

Student *stu = [[Student alloc] init];

stu.age = 25;

stu.gender = 'M';

stu.salary = 5000;

Student *stu1 = [stu copy];

[stu1 printInfo];

}

return 0;

}

上述代码中,以下代码:

Student *stu = [[Student alloc] init];

stu.age = 25;

stu.gender = 'M';

stu.salary = 5000;

定义Student类的一个对象stu,并将对象stu的age属性赋值为25,将对象stu的gender属性赋值为‘M’,将对象stu的salary属性赋值为5000。

上述代码中,以下代码:

Student *stu1 = [stu copy];

[stu1 printInfo];

定义Student类的另一个对象stu1,并将对象stu1赋值为对象stu的副本。由于在Student类中采纳了NSCopying协议,并实现了NSCopying协议中的coptWithZone方法,所以在将[stu copy]赋值给stu1时,是先将对象stu生成一个副本,然后把stu副本的地址赋给指针stu1,这样就使得指针stu和stu1分别指向stu对象和stu对象的副本,实现了深拷贝的功能。

2.3 完整代码

本案例中,类Student声明,即Student1.h文件,完整代码如下所示:

#import <Foundation/Foundation.h>

@interface Student : NSObject<NSCopying>

{

}

@property int age;

@property char gender;

@property double salary;

-(void)printInfo;

@end

类Student实现,即Student.m文件,完整代码如下所示:

#import "Student.h"

@implementation Student

-(id)copyWithZone:(NSZone *)zone

{

Student *stu = [[Student allocWithZone:zone] init];

stu.age = self.age;

stu.gender = self.gender;

stu.salary = self.salary;

return stu;

}

-(void)printInfo

{

NSLog(@"age=%d", _age);

NSLog(@"gender=%c", _gender);

NSLog(@"salary=%lf", _salary);

}

@end

主程序,即main.m,完整代码如下所示:

#import <Foundation/Foundation.h>

#import "Student.h"

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

Student *stu = [[Student alloc] init];

stu.age = 25;

stu.gender = 'M';

stu.salary = 5000;

Student *stu1 = [stu copy];

[stu1 printInfo];

}

return 0;

}

3 模拟系统登录

3.1 问题

编制模拟系统登录程序。从控制台输入用户名、密码登录信息,与保存在文件中的用户名、密码进行对比匹配,如果匹配就显示登录成功,否则显示登录失败。

3.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:从控制台输入用户名

代码如下所示:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

char name[100];

NSLog(@"请输入用户名:");

scanf("%s", name);

NSString *fileName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

}

return 0;

}

上述代码中,以下代码:

NSString *fileName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

是使用NSString类的stringWithCString: encoding:方法,将字符数组name转换成NSString类的对象。stringWithCString: encoding:方法有两个实参,第一个实参是要转换的字符数组名;第二个实参为要转换字符数组的编码方式,对于char型数组,编码方式为NSASCIIStringEncoding。

步骤二:从控制台输入密码

代码如下所示:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

char name[100];

NSLog(@"请输入用户名:");

scanf("%s", name);

NSString *fileName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

char password[100];

NSLog(@"请输入密码:");

scanf("%s", password);

NSString *filePassword = [NSString stringWithCString:password encoding:NSASCIIStringEncoding];

}

return 0;

}

步骤三:从文件中读取用户名

代码如下所示:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

char name[100];

NSLog(@"请输入用户名:");

scanf("%s", name);

NSString *fileName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

char password[100];

NSLog(@"请输入密码:");

scanf("%s", password);

NSString *filePassword = [NSString stringWithCString:password encoding:NSASCIIStringEncoding];

NSError *error = [[NSError alloc] init];

NSString *fileName1 = [NSString stringWithContentsOfFile:@"/users/tarena/desktop/name.txt" encoding:NSUTF8StringEncoding error:&error];

}

return 0;

}

上述代码中,以下代码:

NSError *error = [[NSError alloc] init];

NSString *fileName1 = [NSString stringWithContentsOfFile:@"/users/tarena/desktop/name.txt" encoding:NSUTF8StringEncoding error:&error];

用指定的文件@"/users/tarena/desktop/name.txt"中的内容创建NSString类的对象,从文件中读入的用户名放入对象fileName1。创建对象的方法是使用NSString类的stringWithContentsOfFile: encoding: error:方法,该方法有三个实参,第一个实参是指定文件的含路径文件名;第二个实参是文件内容的编码方式;第三个实参是NSError类的对象,用于获取错误信息。

步骤四:判断用户名是否匹配

代码如下所示:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

char name[100];

NSLog(@"请输入用户名:");

scanf("%s", name);

NSString *fileName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

char password[100];

NSLog(@"请输入密码:");

scanf("%s", password);

NSString *filePassword = [NSString stringWithCString:password encoding:NSASCIIStringEncoding];

NSError *error = [[NSError alloc] init];

NSString *fileName1 = [NSString stringWithContentsOfFile:@"/users/tarena/desktop/name.txt" encoding:NSUTF8StringEncoding error:&error];

if ([fileName1 isEqualToString:fileName] == YES)

{

NSString *filePassword1 = [NSString stringWithContentsOfFile:@"/users/tarena/desktop/password.txt" encoding:NSUTF8StringEncoding error: &error];

if ([filePassword1 isEqualToString:filePassword] == YES)

NSLog(@"登录成功");

else

NSLog(@"用户名或密码错误");

}

else

NSLog(@"用户名或密码错误");

}

return 0;

}

上述代码中,以下代码:

if ([fileName1 isEqualToString:fileName] == YES)

是判断从控制台输入的用户名fileName与从文件中读入的用户名fileName1是否匹配,判断的方法是使用NSString类的isEqualToString方法,该方法有一个实参,是要对比的NSString对象。如果两个对象相同,则返回为真;否则为假。

上述代码中,以下代码:

NSString *filePassword1 = [NSString stringWithContentsOfFile:@"/users/tarena/desktop/password.txt" encoding:NSUTF8StringEncoding error: &error];

用指定的文件@"/users/tarena/desktop/password.txt"中的内容创建NSString类的对象,从文件中读入的密码放入对象filePassword1。

上述代码中,以下代码:

if ([filePassword1 isEqualToString:filePassword] == YES)

NSLog(@"登录成功");

else

NSLog(@"用户名或密码错误");

是判断从控制台输入的密码filePassword与从文件中读入的密码filePassword1是否匹配。如果匹配,则在控制台上输出“登录成功”;否则输出“用户名或密码错误”。

3.3 完整代码

本案例的完整代码如下:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

// insert code here...

char name[100];

NSLog(@"请输入用户名:");

scanf("%s", name);

NSString *fileName = [NSString stringWithCString:name encoding:NSASCIIStringEncoding];

char password[100];

NSLog(@"请输入密码:");

scanf("%s", password);

NSString *filePassword = [NSString stringWithCString:password encoding:NSASCIIStringEncoding];

NSError *error = [[NSError alloc] init];

NSString *fileName1 = [NSString stringWithContentsOfFile:@"/users/tarena/desktop/name.txt" encoding:NSUTF8StringEncoding error:&error];

if ([fileName1 isEqualToString:fileName] == YES)

{

NSString *filePassword1 = [NSString stringWithContentsOfFile:@"/users/tarena/desktop/password.txt" encoding:NSUTF8StringEncoding error:&error];

if ([filePassword1 isEqualToString:filePassword] == YES)

NSLog(@"登录成功");

else

NSLog(@"用户名或密码错误");

}

else

NSLog(@"用户名或密码错误");

}

return 0;

}

4 根据身份证号码,求出生年月日和所属省份

4.1 问题

身份证是公民用于证明持有人身份的证件。

1984年4月,我国开始实行居民身份证制度,第一代居民身份证采用印刷和照相翻拍技术塑封而成,比较容易被伪造。

2003年6月,《中华人民共和国居民身份证法》规定居住在中华人民共和国境内的年满十六周岁的中国公民,应当申请领取居民身份证;未满十六周岁的中国公民,也可以依照本法的规定申请领取居民身份证。

2004年3月起我国正式开始为居民换发内藏非接触式IC卡智能芯片的第二代居民身份证,第二代身份证表面采用防伪膜和印刷防伪技术,使用个人彩色照片,而且内置了数字芯片,采用了数字防伪措施,存有个人图像和信息,可以用机器读取。十六周岁至二十五周岁的,发给有效期十年的居民身份证;二十六周岁至四十五周岁的,发给有效期二十年的居民身份证;四十六周岁以上的,发给长期有效的居民身份证;未满十六周岁的公民,自愿申请领取居民身份证的,发给有效期五年的居民身份证。

自2012年1月1日起,公民申请领取、换领、补领居民身份证,应当登记指纹信息。

4.2 方案

身份证上有一个18位的身份证号,这个号码依据《中华人民共和国国家标准 GB 11643-1999》是这样定义的,从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。出生日期码表示持证人出生的年、月、日。

依据以上的知识,从控制台输入一个含有18位数字的字符串,截取其中的出生日期码,就可以得到持证人的出生日期。

六位数字地址码是这样定义的:头两位表示省份,中间两位表示市,最后两位表示县。这样只要截取其中的头两位,就可知其所在的省份。具体规定如下:

北京|11,天津|12,河北|13,山西|14,内蒙|15,辽宁|21,吉林|22,黑龙江|23,上海|31,江苏|32,浙江|33,安徽|34,福建|35,江西|36,山东|37,河南|41,湖北|42,湖南|43,广东|44,广西|45,海南|46,重庆|50,四川|51,贵州|52,云南|53,西藏|54,陕西|61,甘肃|62,青海|63,宁夏|64,新疆|65,台湾|71,香港|81,澳门|82。

4.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:从控制台输入某人的身份证号

代码如下所示:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

char id[19] = {};

NSLog(@"请输入身份证号:");

scanf("%s", id);

NSString *idString = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];

}

return 0;

}

步骤二:截取出生日期

代码如下所示:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

char id[19] = {};

NSLog(@"请输入身份证号:");

scanf("%s", id);

NSString *idString = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];

NSRange birthday = {6, 8};

NSString *birthdayString = [idString substringWithRange:birthday];

NSLog(@"出生日期为:%@", birthdayString);

}

return 0;

}

上述代码中,以下代码:

NSRange birthday = {6, 8};

定义一个范围birthday,在本案例中这个范围的意义是,从身份证号码第7位开始,连续8个数字。程序中是6,因为字符串中的字符从0开始计算,所以到6时是第7位。

上述代码中,以下代码:

NSString *birthdayString = [idString substringWithRange:birthday];

是截取身份证字符串指定范围内的数字,使用NSString类的substringWithRange方法实现,该方法带有一个实参birthday,是要截取身份证号码从第7位开始,连续8个数字,它们正好是持证人的出生年月日。

步骤三:截取所属省份

代码如下所示:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

char id[19] = {};

NSLog(@"请输入身份证号:");

scanf("%s", id);

NSString *idString = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];

NSRange birthday = {6, 8};

NSString *birthdayString = [idString substringWithRange:birthday];

NSLog(@"出生日期为:%@", birthdayString);

NSString *idData[][2] = {

{@"北京", @"11"},

{@"天津", @"12"},

{@"河北", @"13"},

{@"山西", @"14"},

{@"内蒙", @"15"},

{@"辽宁", @"21"},

{@"吉林", @"22"},

{@"黑龙江",@"23"},

{@"上海", @"31"},

{@"江苏", @"32"},

{@"浙江", @"33"},

{@"安徽", @"34"},

{@"福建", @"35"},

{@"江西", @"36"},

{@"山东", @"37"},

{@"河南", @"41"},

{@"湖北", @"42"},

{@"湖南", @"43"},

{@"广东", @"44"},

{@"广西", @"45"},

{@"海南", @"46"},

{@"重庆", @"50"},

{@"四川", @"51"},

{@"贵州", @"52"},

{@"云南", @"53"},

{@"西藏", @"54"},

{@"陕西", @"61"},

{@"甘肃", @"62"},

{@"青海", @"63"},

{@"宁夏", @"64"},

{@"新疆", @"65"},

{@"台湾", @"71"},

{@"香港", @"81"},

{@"澳门", @"82"}

};

NSString *city = [idString substringToIndex:2];

for (int i = 0; i < 5; i++)

{

NSString *idCity = idData[i][1];

if ([city isEqualToString:idCity] == YES)

{

NSLog(@"所属省份为:%@", idData[i][0]);

break;

}

}

}

return 0;

}

上述代码中,以下代码:

NSString *idData[][2] = {

{@"北京", @"11"},

{@"天津", @"12"},

{@"河北", @"13"},

{@"山西", @"14"},

{@"内蒙", @"15"},

{@"辽宁", @"21"},

{@"吉林", @"22"},

{@"黑龙江",@"23"},

{@"上海", @"31"},

{@"江苏", @"32"},

{@"浙江", @"33"},

{@"安徽", @"34"},

{@"福建", @"35"},

{@"江西", @"36"},

{@"山东", @"37"},

{@"河南", @"41"},

{@"湖北", @"42"},

{@"湖南", @"43"},

{@"广东", @"44"},

{@"广西", @"45"},

{@"海南", @"46"},

{@"重庆", @"50"},

{@"四川", @"51"},

{@"贵州", @"52"},

{@"云南", @"53"},

{@"西藏", @"54"},

{@"陕西", @"61"},

{@"甘肃", @"62"},

{@"青海", @"63"},

{@"宁夏", @"64"},

{@"新疆", @"65"},

{@"台湾", @"71"},

{@"香港", @"81"},

{@"澳门", @"82"}

};

使用一个二维数组,建立省份名与代码之间的联系。

上述代码中,以下代码:

NSString *city = [idString substringToIndex:2];

是从身份证字符串中截取前两位地址码,使用NSString类的substringToIndex方法实现,该方法带有一个实参,表示截取从字符串第一个字符到该实参之间所有字符,形成一个新的字符串。

上述代码中,以下代码:

for (int i = 0; i < 34; i++)

{

NSString *idCity = idData[i][1];

if ([city isEqualToString:idCity] == YES)

{

NSLog(@"所属省份为:%@", idData[i][0]);

break;

}

}

使用一个循环遍历数组,查找身份证上的地址码对应的省份名称。以下代码:

NSString *idCity = idData[i][1];

首先从数组中读取一个地址码。以下代码:

if ([city isEqualToString:idCity] == YES)

判断该地址码与从身份证上截取的地址码是否相同,如果相同,则在控制台上输出该地址码对应的省份名称并结束遍历数组;否则继续遍历数组。

4.4 完整代码

本案例的完整代码如下:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])

{

@autoreleasepool {

char id[19] = {};

NSLog(@"请输入身份证号:");

scanf("%s", id);

NSString *idString = [NSString stringWithCString:id encoding:NSASCIIStringEncoding];

NSRange birthday = {6, 8};

NSString *birthdayString = [idString substringWithRange:birthday];

NSLog(@"出生日期为:%@", birthdayString);

NSString *idData[][2] = {

{@"北京", @"11"},

{@"天津", @"12"},

{@"河北", @"13"},

{@"山西", @"14"},

{@"内蒙", @"15"},

{@"辽宁", @"21"},

{@"吉林", @"22"},

{@"黑龙江",@"23"},

{@"上海", @"31"},

{@"江苏", @"32"},

{@"浙江", @"33"},

{@"安徽", @"34"},

{@"福建", @"35"},

{@"江西", @"36"},

{@"山东", @"37"},

{@"河南", @"41"},

{@"湖北", @"42"},

{@"湖南", @"43"},

{@"广东", @"44"},

{@"广西", @"45"},

{@"海南", @"46"},

{@"重庆", @"50"},

{@"四川", @"51"},

{@"贵州", @"52"},

{@"云南", @"53"},

{@"西藏", @"54"},

{@"陕西", @"61"},

{@"甘肃", @"62"},

{@"青海", @"63"},

{@"宁夏", @"64"},

{@"新疆", @"65"},

{@"台湾", @"71"},

{@"香港", @"81"},

{@"澳门", @"82"}

};

NSString *city = [idString substringToIndex:2];

for (int i = 0; i < 34; i++)

{

NSString *idCity = idData[i][1];

if ([city isEqualToString:idCity] == YES)

{

NSLog(@"所属省份为:%@", idData[i][0]);

break;

}

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: