1.知识点
数组
特点,线性存储,由低地址向高地址排列,数组名为首地址
在函数内
在内存中通过局部变量类型的不同区分是不是数组元素
1).如代码所示:
插入断点,进入调试,按alt+8进入反汇编代码
通过观察反汇编代码,012013D8~012013F4 赋值的大小都是dword4个字节,相同数据类型的局部变量也是一样,
当改变数据类型之后,赋值的数据类型就不同了,因此这种情况下就能判断不是数组了。
数组作为参数
传递数组首地址
2).代码如下:
查看反汇编代码
第一步数组初始化,然后调用函数,获取szHello的地址存放至eax中,通过push将参数传递至Show函数中
寄存器eax值为字符串数组首地址,
函数执行完成之后,在内存对应的地址处值被写入。
数组作为返回值
当作为返回值时,返回的也是首地址,但是存放在函数栈外,函数退出时,将值传递给eax,在栈中这个值也容易被新的数据修改,而产生错误
ex1.
// lab.cpp : 定义控制台应用程序的入口点。
//
/*
1. 定义一个长度为100的字符数组,从键盘获取一个字符串,
将其中的大写字母都转换成为小写字母。;
*/
#include "stdafx.h"
char *ChangeCharacter(char chArray[])
{
for (int i = 0; i < 100; i++)
{
if (chArray[i] <= 'Z' && chArray[i] >= 'A')
{
chArray[i] = chArray[i] + 32;
}
}
return chArray;
}
int _tmain(int argc, _TCHAR* argv[])
{
char szArray[100] = {'\0'};
printf("请输入一串字符:");
for (int i = 0; i < 100; i++)
{
scanf_s("%c", &szArray[i]);
if (szArray[i] == '\n')
{
break;
}
}
char *pszArray;
pszArray = ChangeCharacter(szArray);
printf("%s\r\n", pszArray);
return 0;
}
ex2.
// Lab.cpp : 定义控制台应用程序的入口点。
//
/*
2. 打印一个99乘法表
*/
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
int i, j;
for (i = 1; i <= 9; i++)
{
for (j = 1; j <= 9; j++)
{
if (j > i)
{
break;
}
else
{
printf("%d×%d=%d\t", i, j, i*j);
}
}
printf("\n");
}
return 0;
}
2.知识点
字符串传递
字符串是通过寄存器传递的,寄存器是4个字节,因此每次传递都会按4的倍数传递,不足4字节的按1或者2字节传递
// String.cpp :
// Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
char * my_strcpy(char *a, char *b)
{
char *t = a;
while (*a++ = *b++);
return t;
}
size_t my_strlen(char a[])
{
int length = 0;
while (a[length] != '\0')
{
length++;
}
return length;
}
char * my_strcat(char *dest, char *src)
{
size_t len = strlen(dest);
my_strcpy(&dest[len], src);
return dest;
}
size_t my_puts(char a[])
{
int length = 0;
while (a[length] != '\0')
{
putchar(a[length++]);
}
putchar('\n');
return length;
}
void main( )
{
char string[100];
int i ,num=0,letter=0;
/*letter为0时记录前一状态为空格状态,letter为1时前一状态为字符状态*/
gets(string);
for (i=0;string[i]!='\0';i++)
{
if(string[i]==' '&&letter==1)
letter=0;
if(string[i]!=' '&&letter==0)
{
letter=1;
num++;
}
}
printf("There are %d words.\n",num);
}
3.知识点
变量的作用域
变量在源码中可以被访问到的范围
全局变量
属于进程作用域,整个进程可以访问
在大多情况下,具有初始值的全局变量,在链接时被写入PE文件
静态变量
属于文件作用域,当前源码文件可以访问
局部变量
属于函数作用域,在函数内可以访问
变量的生命周期
变量所在内存从分配到释放这段时间
全局变量和局部变量差别
在于作用域不同,
访问方式不同,局部变量通过栈指针ebp或esp访问,全局变量通过立即数访问
全局变量定义顺序时先定义低地址后定义高地址
局部静态变量与全局变量的生命周期相同,但作用域不同,一般情况下通过设置标志位进行区分,直到一个字节8位使用完。
多次初始化则不再产生变化,不再使用标志位,通过名称粉粹法,在编译期将静态变量重命名,其中包含了作用域及类型等信息。(C++重载也是如此)
堆变量
通过malloc new来实现堆空间申请
利用指针获取到const修饰的变量的地址,强制将指针的const去掉
const int nConst = 5;
int *pConst = (int *)&nConst;
*pConst = 6;
Int nVar = nConst;
#define与const区别
ex1.
// ifdef.cpp : Defines the entry point for the console application. //#ifndef 使用 // #include "stdafx.h" //#define LETTER 0 int main(int argc, char* argv[]) { char str[20]="C Language",c; int i; i=0; while((c=str[i])!='\0') { i++; #ifndef LETTER if(c>='a'&&c<='z') c=c-32; #else if (c>='A' && c<='Z') c=c+32; #endif printf("%c",c); } printf("\n"); return 0; }
4.知识点
指针
是一种数据类型,用于保存数据类型在内存中的地址
多级指针
指针变量存指针的地址
地址
内存标号
指针类型
不同类型的指针决定的是数据长度
下标寻址&指针寻址
下标寻址快但不灵活
指针数组
用于存放多个同类型指针的数组
字符指针数组寻址后是数组成员,二维字符数组寻址后是一维数组首地址
数组指针
当为二维数组时指向一维数组的个元素首地址
函数指针
函数调用时的call指令调用的就是地址,因此函数首地址也可以被指针变量保存
结构体和类的区别
结构体访问默认为public
类默认为private
在反汇编下原理相同,没有分别
ex1.
// Lab.cpp : 定义控制台应用程序的入口点。 // /* 1. 定义3个整型变量及指向整型变量的指针变量, 利用3个指针变量完成数据的输入,从小到大排序,输出 */ #include "stdafx.h" #define MAX_TIME 5 int _tmain(int argc, _TCHAR* argv[]) { int nVarA; int nVarB; int nVarC; int *ptrPointA; int *ptrPointB; int *ptrPointC; ptrPointA = &nVarA; ptrPointB = &nVarB; ptrPointC = &nVarC; scanf_s("%d%d%d", ptrPointA, ptrPointB, ptrPointC); for (int i = 0; i < MAX_TIME; i++) { if (*ptrPointA > *ptrPointB) { *ptrPointA ^= *ptrPointB; *ptrPointB ^= *ptrPointA; *ptrPointA ^= *ptrPointB; } else if (*ptrPointB > *ptrPointC) { *ptrPointB ^= *ptrPointC; *ptrPointC ^= *ptrPointB; *ptrPointB ^= *ptrPointC; } else if (*ptrPointA > *ptrPointC) { *ptrPointA ^= *ptrPointC; *ptrPointC ^= *ptrPointA; *ptrPointA ^= *ptrPointC; } else { break; } } printf("%d %d %d\r\n", *ptrPointA, *ptrPointB, *ptrPointC); return 0; }
ex2.
// lab.cpp : 定义控制台应用程序的入口点。 // /* 2. 不用strcpy函数,实现两个字符串的复制(形参用指针变量) */ #include "stdafx.h" char *MyStringCopy(char *ptrDesString, char *ptrSourString) { char *pszTemp = ptrDesString; if (sizeof(*ptrDesString) < sizeof(*ptrSourString)) { printf("ptrDesString参数空间过小将导致数据丢失!\r\n"); } else if (*ptrSourString == NULL) { printf("ptrSourString为空\t\n"); } else { while (*ptrDesString = *ptrSourString) { if (*ptrSourString == '\0') { break; } else { ptrSourString++; ptrDesString++; } } } return pszTemp; } int _tmain(int argc, _TCHAR* argv[]) { char ArrayDes[100] = { '\0' }; char ArraySour[100] = { '\0' }; char *ptrStringA; ptrStringA = ArrayDes; char *ptrStringB; ptrStringB = ArraySour; scanf_s("%s", ptrStringB, 100); ptrStringA = MyStringCopy(ptrStringA, ptrStringB); for (int i = 0; ArrayDes[i] != '\0'; i++) { printf("%c", ArrayDes[i]); } return 0; }
ex3.
// lab.cpp : 定义控制台应用程序的入口点。 // /* 3. 定义一个结构体,其中包括学号,学生姓名,分数三个成员,定义 一个结构体变量,为其各成员赋初值0,随后修改变量的三个成员为 25,liming,88,随后再屏幕上打印这3各变量的三个成员值 例如: typedef struct _STUINFO { int nNum; char szName[20]; int nScore; }STUINFO,*PSTUINFO; */ #include "stdafx.h" typedef struct _STUINFO { int nNum; char szName[20]; int nScore; }STUINFO, *PSTUINFO; int _tmain(int argc, _TCHAR* argv[]) { _STUINFO StuInfo = {0, '\0', 0}; StuInfo.nNum = 25; StuInfo.nScore = 88; char *sztemp = "liming"; for (int i = 0; i < 20; sztemp++, i++) { StuInfo.szName[i] = *sztemp; if (*sztemp == '\0' ) { break; } } printf("StuInfo.nNum = %d\r\nStuInfo.nScore = %d\r\n", StuInfo.nNum, StuInfo.nScore); printf("StuInfo.szName = "); for (int i = 0; '\0' != StuInfo.szName[i]; i++) { printf("%c", StuInfo.szName[i]); } printf("\r\n"); return 0; }
ex4.// lab.cpp : 定义控制台应用程序的入口点。 // /* 4. 利用结构体类型编写一个程序,实现功能如下: a)根据输入的日期(年月日),求出这天是该年的第几天 b)根据输入的年份和天数,求出对应的日期; 可能需要考虑不同的月份与不同的天数,可能需要考虑润年 */ #include "stdafx.h" struct dayTime { int nYear; int nMounth; int nDay; }; int dayTimeToNumDay(dayTime dt) { int nDayRes = 0; if (dt.nYear % 4 == 0 && dt.nYear % 100 != 0 || dt.nYear % 400 == 0) { switch (dt.nMounth) { case 1: nDayRes = dt.nDay; break; case 2: nDayRes = 31 + dt.nDay; break; case 3: nDayRes = 31 + 29 + dt.nDay; break; case 4: nDayRes = 31 + 29 + 31 + dt.nDay; break; case 5: nDayRes = 31 + 29 + 31 + 30 + dt.nDay; break; case 6: nDayRes = 31 + 29 + 31 + 30 + 31 + dt.nDay; break; case 7: nDayRes = 31 + 29 + 31 + 30 + 31 + 30 + dt.nDay; break; case 8: nDayRes = 31 + 29 + 31 + 30 + 31 + 30 + 31 + dt.nDay; break; case 9: nDayRes = 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + dt.nDay; break; case 10: nDayRes = 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + dt.nDay; break; case 11: nDayRes = 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + dt.nDay; break; case 12: nDayRes = 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + dt.nDay; break; default: break; } } else { switch (dt.nMounth) { case 1: nDayRes = dt.nDay; break; case 2: nDayRes = 31 + dt.nDay; break; case 3: nDayRes = 31 + 28 + dt.nDay; break; case 4: nDayRes = 31 + 28 + 31 + dt.nDay; break; case 5: nDayRes = 31 + 28 + 31 + 30 + dt.nDay; break; case 6: nDayRes = 31 + 28 + 31 + 30 + 31 + dt.nDay; break; case 7: nDayRes = 31 + 28 + 31 + 30 + 31 + 30 + dt.nDay; break; case 8: nDayRes = 31 + 28 + 31 + 30 + 31 + 30 + 31 + dt.nDay; break; case 9: nDayRes = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + dt.nDay; break; case 10: nDayRes = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + dt.nDay; break; case 11: nDayRes = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + dt.nDay; break; case 12: nDayRes = 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + dt.nDay; break; default: break; } } return nDayRes; } dayTime NumDayTodayTime(int nYear, int nNumDay) { dayTime dt; dt.nYear = nYear; if (nYear % 4 == 0 && nYear % 100 != 0 || nYear % 400 == 0) { if (nNumDay > 0 && nNumDay <= 31) { dt.nMounth = 1; dt.nDay = nNumDay; } else if (nNumDay > 32 && nNumDay <= 31 + 29) { dt.nMounth = 2; dt.nDay = nNumDay - 31; } else if (nNumDay > 31 + 29 && nNumDay <= 31 + 29 + 31) { dt.nMounth = 3; dt.nDay = nNumDay - 31 - 29; } else if (nNumDay > 31 + 29 + 31 && nNumDay <= 31 + 29 + 31 + 30) { dt.nMounth = 4; dt.nDay = nNumDay - 31 - 29 - 31; } else if (nNumDay > 31 + 29 + 31 + 30 && nNumDay <= 31 + 29 + 31 + 30 + 31) { dt.nMounth = 5; dt.nDay = nNumDay - 31 - 29 - 31 -30; } else if (nNumDay > 31 + 29 + 31 + 30 + 31 && nNumDay <= 31 + 29 + 31 + 30 + 31 + 30) { dt.nMounth = 6; dt.nDay = nNumDay - 31 - 29 - 31 -30 -31; } else if (nNumDay > 31 + 29 + 31 + 30 + 31 + 30 && nNumDay <= 31 + 29 + 31 + 30 + 31 + 30 + 31) { dt.nMounth = 7; dt.nDay = nNumDay - 31 - 29 - 31 - 30 - 31 -30; } else if (nNumDay > 31 + 29 + 31 + 30 + 31 + 30 + 31 && nNumDay <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31) { dt.nMounth = 8; dt.nDay = nNumDay - 31 - 29 - 31 - 30 - 31 - 30 - 31; } else if (nNumDay > 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 && nNumDay <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30) { dt.nMounth = 9; dt.nDay = nNumDay - 31 - 29 - 31 - 30 - 31 - 30 - 31 -31; } else if (nNumDay > 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 && nNumDay <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) { dt.nMounth = 10; dt.nDay = nNumDay - 31 - 29 - 31 - 30 - 31 - 30 - 31 - 31 - 30; } else if (nNumDay > 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 && nNumDay <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) { dt.nMounth = 11; dt.nDay = nNumDay - 31 - 29 - 31 - 30 - 31 - 30 - 31 - 31 - 30 - 31; } else if (nNumDay > 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 && nNumDay <= 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31) { dt.nMounth = 12; dt.nDay = nNumDay - 31 - 29 - 31 - 30 - 31 - 30 - 31 - 31 - 30 - 31 -30; } else { } } else { if (nNumDay > 0 && nNumDay <= 31) { dt.nMounth = 1; dt.nDay = nNumDay; } else if (nNumDay > 32 && nNumDay <= 31 + 28) { dt.nMounth = 2; dt.nDay = nNumDay - 31; } else if (nNumDay > 31 + 28 && nNumDay <= 31 + 28 + 31) { dt.nMounth = 3; dt.nDay = nNumDay - 31 - 28; } else if (nNumDay > 31 + 28 + 31 && nNumDay <= 31 + 28 + 31 + 30) { dt.nMounth = 4; dt.nDay = nNumDay - 31 - 28 - 31; } else if (nNumDay > 31 + 28 + 31 + 30 && nNumDay <= 31 + 28 + 31 + 30 + 31) { dt.nMounth = 5; dt.nDay = nNumDay - 31 - 28 - 31 - 30; } else if (nNumDay > 31 + 28 + 31 + 30 + 31 && nNumDay <= 31 + 28 + 31 + 30 + 31 + 30) { dt.nMounth = 6; dt.nDay = nNumDay - 31 - 28 - 31 - 30 - 31; } else if (nNumDay > 31 + 28 + 31 + 30 + 31 + 30 && nNumDay <= 31 + 28 + 31 + 30 + 31 + 30 + 31) { dt.nMounth = 7; dt.nDay = nNumDay - 31 - 28 - 31 - 30 - 31 - 30; } else if (nNumDay > 31 + 28 + 31 + 30 + 31 + 30 + 31 && nNumDay <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31) { dt.nMounth = 8; dt.nDay = nNumDay - 31 - 28 - 31 - 30 - 31 - 30 - 31; } else if (nNumDay > 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 && nNumDay <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30) { dt.nMounth = 9; dt.nDay = nNumDay - 31 - 28 - 31 - 30 - 31 - 30 - 31 - 31; } else if (nNumDay > 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 && nNumDay <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) { dt.nMounth = 10; dt.nDay = nNumDay - 31 - 28 - 31 - 30 - 31 - 30 - 31 - 31 - 30; } else if (nNumDay > 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 && nNumDay <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) { dt.nMounth = 11; dt.nDay = nNumDay - 31 - 28 - 31 - 30 - 31 - 30 - 31 - 31 - 30 - 31; } else if (nNumDay > 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 && nNumDay <= 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31) { dt.nMounth = 12; dt.nDay = nNumDay - 31 - 28 - 31 - 30 - 31 - 30 - 31 - 31 - 30 - 31 - 30; } else { } } return dt; } int _tmain(int argc, _TCHAR* argv[]) { dayTime dt; dayTime dt2; dt.nYear = 2017; dt.nMounth = 3; dt.nDay = 10; printf("2017.3.10是第%d天\r\n", dayTimeToNumDay(dt)); int nNumDay = 50; dt2 = NumDayTodayTime(dt.nYear, nNumDay); printf("%d的第%d天是:%d-%d-%d\r\n", dt.nYear, nNumDay, dt2.nYear, dt2.nMounth, dt2.nDay); return 0; }
5.知识点
指针进阶
指针取值
&取地址
指针赋值
*赋值
指针运算
只能进行++ -- + - 运算,
+ 操作数中必须包含整数或枚举类型,若左操作数为整数则右操作数不能为指针
- 运算符,2个指针间隔的单位
数组指针&二位数组
*(array + 1) = array[1]
typeid //C++关键字,返回一个对象的类型
int (*pArray)[3]; //数组指针 可以当作一个行的游标
int *pArray2[3]; //指针数组,保存的地址
指针&多维数组
int arr[2][3][4] = {1,2,3,4,5,6};
int (*p)[3][4]
int *p[2];
int **p[2];
int (*p2[5])[10]; // 数组指针数组,保存了数组指针的数组
二级指针
int *p = &a;
int **p = p;
常见问题
char (*p)[6] = color; // right
char ** p = color; // error
常量数据区无法修改
多级指针
超过一级指针通过一层一层解引用获得各级指针值
函数指针
回调函数时使用
通过tyoedef void (*ptrFun)(int i, int j);
ptrFun FUN(INT N)
{
//返回函数指针
}
文件操作
访问
二进制,文本
FILE结构体
打开
fopen, r:文件需要存在 w:打开文件会覆盖 a ,r+ w+ a+, b二进制方式 t文本方式,fopen_s(&file, "文件", "r+b");
关闭
fclose,
读写
fread(缓冲区,一个字节数,数量, 读取的文件);
fwrite(同上)
其他文件操作
fseek(文件指针, 偏移位置, SEEK_SET//文件开始位置计算偏移值) SEEK_CUR:从当前位置计算偏移, SEEK_END:从文件位置-偏移
ftell()返回当前读写位置
frewind() 将文件定位到文件的开头
fgetc fputc fgets fputs fscanf fprintf feof
结构体读写需要注意对齐
ex1.
// lab.cpp : 定义控制台应用程序的入口点。 // /* 1. 函数指针是指向函数的指针变量,要求定义一个函数, 传入的参数有一个函数指针,和两个整型,通过调用这个 函数指针可以进行任意两个整型运算,请定义三个这种运算函数 并调用(可以参考的运算包括,加减乘除,求两个较大值,较小值等) */ #include "stdafx.h" int(*ptrFunAdd)(int nNumA, int nNumB); int FunAdd(int nNumA, int nNumB) { return nNumA + nNumB; } int _tmain(int argc, _TCHAR* argv[]) { ptrFunAdd = FunAdd; int Res = ptrFunAdd(5, 6); printf("%d\r\n", Res); return 0; }
ex2.// lab.cpp : 定义控制台应用程序的入口点。 // /* 2. 从键盘上输入一串字符串,要求将字符串内容以二进制方式输出到磁盘文件中, 再次从磁盘文件中读取字符串到字符数组中,并打印到屏幕上 */ #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { char szArray[20] = {'\0'}; int numclosed = 0; FILE *stream; char list[20] = {'\0'}; printf("请输入一串字符串:"); for (int i = 0; i < 20; i++) { scanf_s("%c", &szArray[i]); if (szArray[i] == '\n') { break; } } if ((stream = fopen("1.dat", "w+b")) == NULL) { printf("The file '1.dat' was not opened\n"); } else { printf("The file '1.dat' was opened\n"); /* Write 25 characters to stream */ fwrite(szArray, sizeof(char), 20, stream); fseek(stream, 0, SEEK_SET); fread(list, sizeof(char), 20, stream); } for (int i = 0; i < 20; i++) { if (list[i] == '\n') { break; } printf("%02x ", list[i]); } printf("\r\n"); if (fclose(stream)) printf("The file 'data' was not closed\n"); /* All other files are closed: */ numclosed = _fcloseall(); return 0; }
ex3.// day.cpp : 定义控制台应用程序的入口点。 // /* 3. 通过文件操作,通过解析命令的方式,使你的控制台程序能够有 拷贝,剪切功能。 例如: X d:\a.txt d:\1\a1.txt C d:\a.txt d:\1\a1.txt 第一行能够实现,将d盘中的a.txt剪切到e盘1文件夹中,命名为a1.txt 第二行能够实现,将d盘中的a.txt复制到e盘1文件夹中,命名为a2.txt ****由于没有E盘,所以使用D盘不同目录,使用命令行参数可以实现, ****但还是使用在程序内获得参数 */ #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { FILE *pFile, *pFile2; char chComd = '\0'; int nCount = 0; //chComd = argv[1]; printf("输入命令模式(X:剪切,C:复制):"); scanf_s("%c", &chComd); fflush(stdin); char chPathSrc[20] = { "\0" }; printf("输入原文件路径#结束:"); for (int i = 0; i < 20; i++) { //chPathSrc[i] = getchar(); nCount = i; scanf_s("%c", &chPathSrc[i]); if ('#' == chPathSrc[i]) { break; } } char chPathSrcTemp[20] = { "\0" }; for (int i = 0; i < nCount; i++) { chPathSrcTemp[i] = chPathSrc[i]; } fflush(stdin); char chPathDes[20] = { '\0' }; printf("输入目的文件路径#结束:"); for (int i = 0; i < 20; i++) { nCount = i; scanf_s("%c", &chPathDes[i]); if (chPathDes[i] == '#') { break; } } char chPathDesTemp[20] = { "\0" }; for (int i = 0; i < nCount; i++) { chPathDesTemp[i] = chPathDes[i]; } if ((pFile = fopen(chPathSrcTemp/*(char*)argv[2]*/, "r")) == NULL) { printf("open file failed!\r\n"); } else { char szbuffer[512] = { '\0' }; fread(szbuffer, sizeof(char), 512, pFile); if ((pFile2 = fopen(chPathDesTemp/*(char*)argv[3]*/, "w")) != NULL) { fwrite(szbuffer, sizeof(char), 512, pFile2); fclose(pFile2); } fclose(pFile); //删除a.txt if (chComd == 'x' || chComd == 'X') { remove(chPathSrcTemp/*(char*)argv[2]*/); printf("剪切完成!\r\n"); } if (chComd == 'c' || chComd == 'C') { printf("复制完成!\r\n"); } } return 0; }