IO:DAY1 标准IO函数

该程序使用C语言实现,包括用户登录验证和注册功能。登录时检查账户和密码是否存在,注册时防止用户名重复。另外,还封装了一个函数用于计算文件的行数和字符总数。

第一题:

1. touch有一个usr.txt的文件,其中存储着用户的账户和密码,格式如下:
a.zhangsan aaaa
b. lisi bbbbb
c.空格前面是账户,空格后面是密码,一行一个账户、密码
2要求如下:
a.从终端获取一个账户名和密码
b.判断是否能够登录成功
c.若账户不存在:则提示账户不存在
d.若账户存在,密码不匹配:则提示密码错误
e.账户密码均存在:则显示登录成功。

加一个注册功能,要求不能重复

#include <stdio.h>
#include <string.h>
int main(int argc, const char *argv[])
{
	FILE* fp = fopen("./usr.txt","a+");
	FILE* fq = fopen("./usr.txt","r");
	if(NULL == fp)
	{
		perror("fopen");
		return -1;
	}
	if(NULL == fq)
	{
		perror("fopen");
		return -1;
	}
	char new_id[20];
	char new_passwd[20];
	char name[20];
	char passwd[20];
	char file_name[32],file_passwd[32];

	printf("注册:请输入你的昵称:");
	scanf("%s",new_id);
	printf("请输入你的密码:");
	scanf("%s",new_passwd);
	while(1)
	{
		if(fscanf(fp,"%s %s",file_name,file_passwd)==EOF)
		{
			break;
		}
		if(strcmp(file_name,new_id)==0)
		{
			printf("用户名存在,注册失败\n");
			break;
		}
		
		fprintf(fp,"%s %s\n",new_id,new_passwd);
		printf("创建成功\n");
	} 
	printf("请输入用户名和密码:");
	scanf("%s %s",name,passwd);
	printf("用户名:%s 密码:%s\n",name,passwd);
	while(1)
	{
		if(fscanf(fq,"%s %s",file_name,file_passwd)==EOF)
		{
			printf("用户不存在\n");
			break;
		}
		//比较名字,名字相同比较密码,都相同跳出循环
		if(strcmp(name,file_name)==0)
		{
			if(strcmp(passwd,file_passwd)==0)
			{
				printf("用户登陆成功\n");
			}
			else
			{
				printf("密码错误");
			}
			break;
		}
		//用户账户不相同,则继续读取下一个账户密码
	}
	if(fclose(fp)==EOF)
	{
		perror("fclose");
		return -1;
	}
	if(fclose(fq)==EOF)
	{
		perror("fclose");
		return -1;
	}

	return 0;
}

 

 

2、计算一个文件的行数,大小,并封装成一个函数 

#include <stdio.h>
void Count(FILE *fp)
{
	int count=0;
	int line=0;
	while(1)
	{
		int c=fgetc(fp);
		if((EOF==c))
			break;
		count++;
		if('\n'==c)
			line++;
	}
	printf("有%d行,有%d个字符\n",line,count);

}
int main(int argc, const char *argv[])
{
	FILE* fp=fopen(argv[1],"r");
	if(NULL == fp)
	{
		perror("fopen");
		return -1;
	}
	Count(fp);

	if(fclose(fp)==EOF)
	{
		perror("fclose");
		return -1;
	}
	return 0;
}

 

### 构造函数定义与初始化列表的区别 在C++中,构造函数用于初始化类的成员变量,但构造函数体内的赋值和初始化列表中的初始化在行为和用途上有显著的区别。以下内容将从构造函数的不同定义方式和初始化列表的作用进行详细分析。 #### 构造函数的定义方式 C++允许定义不同形式的构造函数,包括无参构造函数、带参构造函数和全缺省构造函数。例如: ```cpp class Date { public: // 无参构造函数 Date() { _year = 1; _month = 1; _day = 1; } // 带参构造函数 Date(int year, int month, int day) { _year = year; _month = month; _day = day; } // 全缺省构造函数 Date(int year = 1, int month = 1, int day = 1) { _year = year; _month = month; _day = day; } private: int _year; int _month; int _day; }; ``` 上述代码中,构造函数体内的赋值操作是对成员变量进行赋值,而不是初始化。构造函数体内的赋值行为可以多次发生,而初始化只能进行一次[^4]。 #### 初始化列表的作用 初始化列表是一种在构造函数中直接初始化成员变量的语法,它允许在构造函数体执行之前完成成员变量的初始化。初始化列表特别适用于以下几种情况: - **常量成员变量**:常量必须在初始化时赋值,不能在构造函数体内赋值。 - **引用成员变量**:引用必须在初始化时绑定到对象上。 - **没有默认构造函数的类类型成员变量**:如果一个成员变量的类型没有默认构造函数,必须通过参数进行初始化[^2]。 例如: ```cpp class Rectangle { public: Rectangle(int val) : a(val), b(val), c(a) {}; // 构造函数初始化列表 void show() { cout << a << endl; cout << b << endl; cout << c << endl; } private: int a; const int b; int &c; }; ``` 在这个例子中,`a`、`b`和`c`分别通过初始化列表进行初始化。`b`是一个常量,必须在初始化列表中赋值;`c`是一个引用,必须绑定到一个对象上[^3]。 #### 初始化列表与构造函数的区别 初始化列表和构造函数体内的赋值有本质区别。初始化列表是在对象构造时直接进行初始化,而构造函数体内的赋值是在对象已经构造完成之后进行的。这意味着初始化列表可以确保成员变量在构造时就已经具有了合适的初始值,而构造函数体内的赋值则可能涉及多次赋值操作[^4]。 此外,对于派生类来说,必须通过初始化列表显式调用基类的某个构造函数,否则只会调用基类的默认构造函数。例如: ```cpp class Widget : public Base { const int ci; // 常量成员 std::string name; // 复杂类型 int &ref; // 引用成员 public: // 合法:ci、ref、Base 都只能在列表中初始化 Widget(int v, std::string nm, int &r) : Base(v), ci(v + 1), name(std::move(nm)), ref(r) { // 构造函数体:不再需要赋值 } }; ``` 在这个例子中,`Base(v)`是通过初始化列表调用基类构造函数,`ci(v + 1)`是对常量成员的初始化,`name(std::move(nm))`是对复杂类型的直接初始化,`ref(r)`是对引用成员的绑定[^5]。 #### 构造函数定义的区别 构造函数的定义方式会影响初始化的方式。例如,`OperationalLoadPort::OperationalLoadPort()`和`OperationalLoadPort::OperationalLoadPort(int i)`是两个不同的构造函数。前者是一个无参构造函数,后者是一个带参构造函数。它们的区别在于构造函数的参数列表不同,导致初始化的方式和内容也不同。无参构造函数通常用于设置默认的初始值,而带参构造函数则允许在创建对象时传入具体的初始值。 #### 初始化顺序 成员变量的初始化顺序由它们在类中声明的顺序决定,与初始化列表中书写顺序无关。这意味着即使初始化列表中的顺序与类中声明的顺序不同,初始化仍然会按照类中声明的顺序进行[^5]。 ### 相关问题 1. 如何在C++中使用初始化列表? 2. 为什么不能在构造函数体内初始化常量成员变量? 3. 初始化列表对派生类的构造函数有什么影响? 4. 成员变量的初始化顺序是否会影响程序的运行结果? 5. 如何在C++中处理没有默认构造函数的成员变量?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值