(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;
}
相关文章推荐
- Objective-c---分类 、 扩展 、 ARC
- Objective-C语言介绍 、 Objc与C语言 、 面向对象编程 、 类和对象 、 属性和方法 、 属性和实例变量
- Objective-C--- 多态 、 协议
- Objective-C对象初始化 、 实例方法和参数 、 类方法 、 工厂方法 、 单例模式
- Objective-C----MRC内存管理 、 自动释放池 、 面向对象三大特性及封装 、 继承 、 组合与聚合
- Objective-C对象初始化 、 实例方法和参数 、 类方法 、 工厂方法 、 单例模式
- Objective-C语言介绍 、 Objc与C语言 、 面向对象编程 、 类和对象 、 属性和方法 、 属性和实例变量
- ArcEngine(ArcObjects) java开发环境配置
- Android学习第七天————将数据保存为JSON格式,通过JSONObject和JSONReader来解析JSON数据
- a different object with the same identifier value was already associated with the session
- Object类
- for,for-in和enumerateObjectsUsingBlock的比较
- python 安装pandas 出现InsecurePlatformWarning: A true SSLContext object is not available.
- Objective-c语言_复合
- 显示所有数据库 mysql_fetch_object()
- Objective-c语言_对可变数组NSMutableArray
- Objective-c语言_对不可变数组NSArray
- java泛型与object的比较
- difference between string literal and string object
- Swift学习: 从Objective-C到Swift