system(”cls“)清屏
Ctrl + / 注释
输出阻塞解决
fflush(stdout);
字符(串)操作
输入字符串
不能直接输入字符串到字符指针char *p;scanf("%s",p);
只是定义了指针 p ,但并没设定具体的指向,故无法存储数据。
你应该这样用:
char s[255];char *p=s;scanf("%s",p)
或const int maxlength=100;
char *p=(char*)malloc(maxlength*sizeof(char));
scanf("%s",p);
为什么可以char*p;p="asdf" 这样赋值,这个也没有把指针初始化啊?
“asdf”是常量字符串,是在编译时就已经分配空间了的,p 被初始化为指向该空间。
你的程序中字符串是读入的,并没有提前分配空间。
gets(s)函数
gets(s)函数与scanf("%s:",&s)/*scanf("%s",s) */相似,但不完全相同,使用scanf("%s",&s);函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止。
复制字符串
strcpy(字符数组1,字符串2)
比较字符(串)
若是字符串,则需要使用字符串函数了,strcmp
strcmp(s1,s2)
cmp 是 compare,比较的缩写。
设这两个字符串为str1,str2,
若str1==str2,则返回零;
若str1<str2,则返回负数;
若str1>str2,则返回正数。
比较字符可以直接使用==比较操作符,
也可以忽略大小写来比较,使用函数stricmp 中间的i意思是ignore case sensitive
还可以指定长度比较,strncmp,如:
chars1[]="abc",s2[]="abcdefg";
if(strncmp(s1,s2,3)==0) printf("first3 characters are same");
若不是从开头位置开始比较,如:
chars1[]="abc",s2[]="xyzabc"
if(strncmp(s1,&s2[3],3)==0) 就是比较s1和s2的第3个字符开始的内容
拼接字符串
strcat()函数 ,即stringcatenate的缩写
使用时字符串需初始化否则会出现乱码: char name[33] = { 0 }; char input[15] = { 0 };
原型:externchar *strcat(char *dest,char *src); 用法:#include<string.h> 功能:把src所指字符串添加到dest结尾处(覆盖dest结尾处的'\0')并添加'\0'。 说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回指向dest的指针。
#include <stdio.h>
#include <string.h>
intmain(){
char d[20]="字符串1"; //第一个字符串
char *s=" 字符串2"; //第二个字符串
strcat(d,s); //拼接两个字符串,结果保存在第一个字符串当中
printf("%s",d); //输出拼接结果:"字符串1字符串2"
getchar();
return 0;
}
getchar()
消除缓冲区的字符
回车不能被scanf("%s",fileName);接收
除非写作scanf(" %s",fileName);或scanf("%*c%s",fileName);或scanf("%[^\n]",fileName);
目的都是不接收或者跳过回车符,防止接收空字符串
两个getchar函数的目的都是为了吸收上一次输入的回车符,以防止gets获取空字符串
getchar()函数等待输入直到按回车才结束,回车前的所有输入字符都会逐个显示在屏幕上,但只有第一个字符作为函数的返回值。
getchar函数原型如下:
函数格式:int getchar(void);
功 能:从标准输入设备读取下一个字符
把enter键所表示的字符接收
Melloc分配内存
memory allocate
fopen
函数原型:FILE * fopen(const char * path, const char * mode);
返回值:
文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回 NULL,并把错误代码存在errno中。
一般而言,打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在 fopen() 后作错误判断及处理。
参数说明:
参数 path字符串包含欲打开的文件路径及文件名,参数 mode 字符串则代表着流形态。
mode 有下列几种形态字符串:
字符串 说明
r 以只读方式打开文件,该文件必须存在。
r+ 以读/写方式打开文件,该文件必须存在。
rb+ 以读/写方式打开一个二进制文件,只允许读/写数据。
rt+ 以读/写方式打开一个文本文件,允许读和写。
w 打开只写文件,若文件存在则长度清为 0,即该文件内容消失,若不存在则创建该文件。
w+ 打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
a 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF 符保留)。
a+ 以附加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的 EOF 符不保留)。
wb 以只写方式打开或新建一个二进制文件,只允许写数据。
wb+ 以读/写方式打开或建立一个二进制文件,允许读和写。
wt+ 以读/写方式打开或建立一个文本文件,允许读写。
at+ 以读/写方式打开一个文本文件,允许读或在文本末追加数据。
ab+ 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。
提前结束函数用return
if(gra==NULL){
printf("没有可读文件,请确认是否放入文件!");
return0;
}
Main接收参数
c语言中main函数参数argc,argv说明,及命令行中如何传参数
C/C++语言中的main函数,经常带有参数argc,argv,如下:
int main(int argc, char** argv)
int main(int argc, char* argv[])
这两个参数的作用是什么呢?argc 是指命令行输入参数的个数,argv存储了所有的命令行参数。假如你的程序是hello.exe,如果在命令行运行该程序,(首先应该在命令行下用 cd 命令进入到 hello.exe 文件所在目录)运行命令为:
hello.exe Shiqi Yu
那么,argc的值是 3,argv[0]是"hello.exe",argv[1]是"Shiqi",argv[2]是"Yu"。
下面的程序演示argc和argv的使用:
#include <stdio.h>
int main(int argc, char ** argv)
{
int i;
for (i=0; i < argc; i++)
printf("Argument %d is %s./n", i, argv[i]);
return 0;
}
假如上述代码编译为hello.exe,那么运行
hello.exe a b c d e
将得到
Argument 0 is hello.exe.
Argument 1 is a.
Argument 2 is b.
Argument 3 is c.
Argument 4 is d.
Argument 5 is e.
&*
引用一个SqQueue*类型的变量。
'&'表示变量p是个引用,SqQueue*整个表示引用的类型。举个例子:
void test(int *&p)
{
p++;
}
void main()
{
int a[3]={0,1,2}, *p;
p=a;
test(p);
printf("%d\n", *p);// 输出的是1
}
在结构体中定义结构体指针
在c语言中,结构体中不可以再定义结构体变量,但可以定义结构体指针!c++中可以。
C结构体中定义结构体报错:[Error] baseoperand of '->' has non-pointer type 'QData'
定义eg:
1. typedef struct tagStudent_T
2. {
3. int i_StuID;
4. int i_StuClass;
5. }Student_T;
6.
7. typedef struct tagSchool_T
8. {
9. Student_T *student;
10. int i_SchoolRank;
11. }School_T;
含有指针成员的结构体使用总结
在C++中经常用到结构体和指针,当定义一个结构体,结构体成员中有指针的时候,需要注意很多。一下分为:结构体初始化、结构体作为函数参数、函数返回值、以及结构体指针的情况进行总结。
一、含有指针成员的结构体初始化
含有指针成员的结构体初始化的时候,必须给指针成员给一个明确的地址。注意:给指针成员初始化的时候,要么给其一个地址,比如是数组数组地址的时候,就可以通过指针来操作数组,也可以一个变量的地址;还可以给其新建一段内存,就是new一段内存,内存的地址由系统决定。如果含有指针的结构体在初始化之前直接对指针进行操作,会出现错误,因为指针必须先初始化再操作。
以下是示例:
[cpp] view plain copy
struct keypoint
{
int x;
int y;
int* data;
int number;
};
keypoint point;
point.x = 1;
point.y = 0;
point.number = NUMBER;
for (int i = 0; i < NUMBER; i++)
{
point.data[i]= i; //会出错,因为为初始化指针,就直接使用
}
必须为其指针初始化赋值:
[cpp] view plain copy
point.data = new int [NUMBER];
这样就可以。
二、含有指针成员的结构体作为函数参数
当含有指针成员的结构体作为函数参数的时候,通过形参将结构体传入函数,结构体变量中的指针指向的变量变化可以保存,但是一般变量的变化不能保存。如果要保存一般变量的变化,需将函数参数写成引用的类型&。
在上述的代码基础上:
[cpp] view plain copy
keypoint point0;
point0.x = 10;
point0.y = 10;
point0.number = 100;
point0.data = new int[point0.number];
for (int j = 0; j < 100; j++)
point0.data[j] = j;
changeKeypoint(point0);<spanstyle="white-space:pre"> </span>//运行结果data指向的数据每个数据都改变了,但是x和y的值没有变化。
<pre name="code"class="cpp">//函数定义
void changeKeypoint(keypointkeypoints)
{
keypoints.x += 1000;
keypoints.y += 1000;
for (int i = 0; i < keypoints.number; i++)
{
keypoints.data[i] += 1000;
}
}
但是如果将函数改为:
[cpp] view plain copy
void changeKeypoint(keypoint&keypoints)<span style="white-space:pre"> </span>//函数参数为引用类型
{
keypoints.x += 1000;
keypoints.y += 1000;
for (int i = 0; i < keypoints.number; i++)
{
keypoints.data[i] += 1000;
}
}
这样就可以实现对结构体变量的x和y值的改变。
三、含有指针成员的结构体作为函数返回值
可以直接将结构体和一般类型的变量(比如int、double等)返回。
[cpp] view plain copy
keypoint point0 = SetPoint();<spanstyle="white-space:pre"> </span>//points结构体的x、y和指针的数据值都能返回
//函数定义
keypoint SetPoint()
{
keypoint point0;
point0.x = 10;
point0.y = 10;
point0.number = 100;
point0.data = new int[point0.number];
for (int j = 0; j < 100; j++)
point0.data[j] = j;
return point0;
}
运行结果:
[cpp] view plain copy
point0.x = 10, <prename="code" class="cpp">point0.y = 10,
[cpp] view plain copy
<pre name="code"class="cpp">point0.data[j] = j; //j从0到100
四、含有指针成员的结构体的指针
可以定义指向结构体的指针,即指针指向的是一个结构体,指针存放的是一结构体的指针。
[cpp] view plain copy
keypoint* points;
points->x = 0;
points->y = 10;
points->data = new int [100];
链式结构注意
p=NULL不能省略,p不会自动=NULL,会有默认地址但又没有真正内容