自己对于写程序还处于菜鸟阶段,很多用法尚未涉及或者还不清晰。总是想着等每个程序写完再来总结,却发现早已无从下手。于是想到了这个方法,每次遇到问题并解决之后第一时间到这个日志上记录下来。于是有了此文。
ivandark 处于边缘的菜的不能再菜的程序猴子一年半
——2012.11.10
1.声明空间并初始化内存
声明空间: 一维:int *a; a = (int*)malloc(sizeof(int)*size); //size为数组大小
二维:int **a; a=(int**)malloc(sizeof(int*)*row); //
for(int i=0;i<col;i++)
{
a[i] = (int*)malloc(sizeof(int)*col);
}
初始化内存:因为不初始化,动态声明的数组赋值不正常
一维和二维的初始化是不一样的。
一维:memset(a,0,sizeof(a));
二维:边分配内存边初始化:
int **a; a=(int**)malloc(sizeof(int*)*row); //
for(int i=0;i<col;i++)
{
a[i] = (int*)malloc(sizeof(int)*col);
memset(a[i],0,sizeof(int)*col); // 貌似只能这么写 不可以效仿一维的格式
}
删除: free(a); //一维和二维的一样
如果你像上面对a分配刚好的够用的内存并对其赋值运算,再释放会出现错误after normal block(#207) at 。
经过查找发现不少人曾经出现过此问题。
原因描述(引用网络):这是典型的内存溢出错误,常在内存的delete处发生,而且一般在debug版本中可能出现,release版本中可能并不报错.出现这个错误的原因一般都是malloc/new申请的内存溢出.因为在c++中,如果用new分配一段内存,操作的时候改变了该部分的大小,在delete时就会出错.
因为申请了一个size为5的内存,但是strcpy过去了一个size为6的字符串,因此破坏了这个指针,运行debug版本的时候就 会出现先前的错误,但是在release版本中,溢出一个字节的内存很有可能是没有错误的,然后潜在的隐患是肯定存在的,因此,我们在debug遇到这样 的错误时候一定要仔细检查对new/malloc出的指针的操作.
解决方案:我是为a数组多分配了一个(int**)内存 程序运行正常
2.C语言读取txt文本
txt格式是我们利用编程语言处理数据时,数据常用的存储格式。
下面介绍常用的用于读写的函数:
打开:FILE *fp; if((fp=fopen("E:\\test.txt","rt"))==NULL) //" "里面的是文件路径 "rt"表示读取方式 {printf("cannot open file\n");return; }
关闭:fclose(fp);
读取:这里分为很多函数:
fscanf();这个是个人感觉比较好用的。从一个流中执行格式化输入,fscanf遇到空格和换行时结束,注意空格时也结束。这与fgets有区别,fgets遇到空格不结束。比如我们想把fp中的数据存到二维数组a中 ("%f"表示以浮点形式读取)
for(i=0;i<M;i++){for(j=0;j<N;j++)fscanf(fp,"%f",&a[i][j]);}
fread(); fread( void *buffer, size_t size, size_tcount, FILE *stream);根据msdn中的说明不难使用,这里不赘述。
写入:
fwrite(); :fwrite(buffer,size,count,fp); (1)buffer:是一个指针,对fwrite来说,是要输出数据的地址。 (2)size:要写入的字节数; (3)count:要进行写入size字节的数据项的个数; (4)fp:目标文件指针。
3.VC读取txt文本
对话框形式打开:
void COpenDataDlg::OnBtnOpendata()
{
// TODO: Add your control notification handler code here
static char BASED_CODE file[] = "TXT Files (*.TXT)|*.txt|所有文件(*.*)|*.*||"; //文件类型说明字符串
CFileDialog SelectFile (TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,file,NULL);
//文件对话框初始化(点击浏览时候的对话框) 第一个TRUE表示以打开方式;false是以保存的方式;file表示打开的是什么文件其他参数 显示对话框 隐藏只读,
SelectFile.DoModal(); //弹出对话框
CString FileName;
FileName=SelectFile.GetPathName();//得到所选文件路径
m_FileName = FileName;
UpdateData(FALSE);//把后台数据刷新到前台显示
}
读取:跟C语言相同。好像可以用vc中的方法 CFile什么的,但是暂时没搞懂,先放着。输出:跟C相同。
char str[50]; //数组大小可以根据输出的内容大小而定,这里为了简便声明了静态数组
CFile file(_T("E:\\result.txt"), CFile::modeCreate | CFile::modeWrite);
for(i=0; i<8; i++) //8是要输出的字符的个数 可以根据需要变化 或者先求一个长度再用长度变量替换8
{
sprintf(str, "%d,%d\r\n",i,showID[i]); //showID里存储的是要写入数据
file.Write(str, strlen(str) * sizeof(char));
}
file.Close();
MessageBox("结果已输出到E:\\result.txt");
4.opencv取像素灰度宏
(CV_IMAGE_ELEM(pImg1,uchar,i,j) //注意i j i代表y轴方向 j代表x轴方向 别弄反了
5.程序在调试态下正常,执行时候mfc基础类停止运行
DAMAGE:After normal block(#****)
这种问题通常是由于动态分配内存导致的。可以检查一下以下三种情况:
int a[5];
a[5] = 3; //越界了
int *a;
int lenth1 = 2;
int lenth2 = 3;
a = (int*)malloc(sizeof(int)*lenth1);
memset(a,0,sizeof()*lenth2);
free(a);
这里初始化的数组长度比定义的要长,出错
6.最近用过的Opencv 函数
(1)CvMat 创建并初始化矩阵
CvMat Ma;
cvInitMatHeader(&Ma,row,col,CV_64FC1,FC,CV_AUTOSTEP);//CV_64FC1 表示64位浮点数 可以根据需要换成其他
(2)cvEigenVV
见另一篇转载文章 http://blog.youkuaiyun.com/ivandark/article/details/8228029
(3)cvGetSize 得到矩阵尺寸 返回CvSize结构体
例如: CvSize size;
size = cvGetSize(IplImage* img); //返回图像长宽
(4) cvSaveImage
保存图像到文件
int cvSaveImage( const char* filename, const CvArr* image ); //filename 直接给路径名,用字符串 指针用图像的指针 比如IplImage filename 文件名。 image 要保存的图像。 函数cvSaveImage保存图像到指定文件。 图像格式的的选择依赖于filename的扩展名,请参考cvLoadImage。只有8位单通道或者3通道(通道顺序为'BGR' )可以使用这个函数保存。如果格式,深度或者通道不符合要求,请先用cvCvtScale 和cvCvtColor转换;或者使用通用的cvSave保存图像为XML或者YAML格式。 IplImage* KL_Img1;
CvSize size = cvGetSize(pImg1);
KL_Img1 = cvCreateImage(size, 8, 1); // 创建8位单通道图像
memset(KL_Img1->imageData, 0.0,sizeof(KL_Img1->imageData));// 将内存拷贝到图像中的imageData中
7.如何重绘
fp2 = fopen("E:\\STU\\result.txt","w");
int main()
{
FILE *fp;
fp = fopen("E:\\a.txt","r");
fseek(fp,0L,SEEK_END);//移动文件指针到末尾
int len = ftell(fp1);//顺便求个长度呗 经过试验 txt中 空格算一个长度 回车算两个
//ftell用于得到文件位置指针当前位置相对于文件首的偏移字节数
fseek(fp,0L,SEEK_SET);//把文件指针再移动到开始
fseek(fp,100L,SEEK_SET); //再把文件指针移动到离文件开头处100字节
fseek(fp,100L,SEEK_CUR); //再把文件指针移动到离当前位置处100字节
fseek(fp,100L,SEEK_END); //再把文件指针移动到离文件结尾处100字节
fseek(fp,-100L,SEEK_SET);//再把文件指针"退回"到离文件结尾处100字节
return 0;
}
while(!feof(fp1)) //从文件中读取字符串 并计算字母字符的个数
{
ch = fgetc(fp1); //一个一个字符的读
if(ch==EOF)//文件末端
{
printf("%d",count);
printf("\n");
}
if(isalpha((int)ch))//判断ch是否为字母 字母的ASCII码:ASCII码:65~90号为26个大写英文字母,97~122号为26个小写英文字母!!!
{
str[count] = ch; //存入字符串中
count++;
}
}
char msg[] = "Hello world";
int i = 0;
//方法一
while (msg[i]&&(i<strlen(msg)))
{
fputc(msg[i], fp1);
i++;
}
//方法二
fprintf(fp1,"%s",msg);
//isalpha:检查ch是否是字母 是字母则返回非0 否则返回0
if(isalpha((int)ch))...//判断ch是否为字母 char ch
//isdigit:检查ch是否为数字0-9 是则返回非0 否则返回0
//islower:检查是否为小写字母
//isupper:检查是否为大写字母
//isalnum:检查是否是字母或数字
//ispunct:是否是标点字符
//isspace:是否是空格符/跳格符/控制字符/换行符
ch = tolower((int)ch);//大写字母转成小写字母 ; toupper小写转大写
D.fgets —— 读取字符串
int main()
{
FILE *fp1;
fp1 = fopen("E:\\test.txt","r");
char msg1[20];
char msg2[20];
fgets(msg1,4,fp1); //m=4
fgets(msg2,7,fp1); //n=7
printf("%s\n",msg1);
printf("%s\n",msg2);
return 0;
}
情况一:(m=4 n=7)
unsigned char *tmp = (unsigned char*)malloc(sizeof(unsigned char)*256*256);
memset(tmp,0,sizeof(tmp));
fread(tmp,sizeof(unsigned char),256*256,fp1);
memset(data,0,sizeof(data));
for(i=0;i<=255*255;i++)
{
data[i] = (int)tmp[i];
}