自己在CODING过程中遇到的问题以及解决(C/VC)
自己對于寫程序還處于菜鳥階段,很多用法尚未涉及或者還不清晰。總是想著等每個程序寫完再來總結,卻發現早已無從下手。于是想到了這個方法,每次遇到問題并解決之后第一時間到這個日志上記錄下來。于是有了此文。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 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來說,是要輸出數據的地址?! ?#xff08;2)size:要寫入的字節數; (3)count:要進行寫入size字節的數據項的個數; (4)fp:目標文件指針。
3.VC讀取txt文本
對話框形式打開:
void COpenDataDlg::OnBtnOpendata() {// TODO: Add your control notification handler code herestatic 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(#****)
這種問題通常是由于動態分配內存導致的??梢詸z查一下以下三種情況:
(1)數組訪問越界 int a[5]; a[5] = 3; //越界了(2)動態分配數組越界 int *a; int lenth1 = 2; int lenth2 = 3; a = (int*)malloc(sizeof(int)*lenth1); memset(a,0,sizeof()*lenth2); free(a);這里初始化的數組長度比定義的要長,出錯 (3)動態聲明的空間沒有被釋放 所有動態聲明的數組在一個函數結束之后一定一定要free掉! 但是在子函數中好像是無所謂的。只要在功能的主函數中釋放即可。
6.最近用過的Opencv 函數
(1)CvMat 創建并初始化矩陣
(2)cvEigenVV?
見另一篇轉載文章 ??http://blog.csdn.net/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格式。保存圖像到文件 int cvSaveImage( const char* filename, const CvArr* image ); filename 文件名。 image 要保存的圖像。 函數cvSaveImage保存圖像到指定文件。圖像格式的的選擇依賴于filename的擴展名,請參考cvLoadImage。只有8位單通道或者3通道(通道順序為'BGR' )可以使用這個函數保存。如果格式,深度或者通道不符合要求,請先用cvCvtScale 和cvCvtColor轉換;或者使用通用的cvSave保存圖像為XML或者YAML格式。
(5)初始化 IplImage* 明確 ?IplImage* 中的灰度數據存在imageData里 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.如何重繪 所謂重繪,就是講程序中變量保存的數據源源不斷的刷新到界面上。實現過程大概可以分為如下幾步: (1)以繪制點為例,先在VIew里設置一個變量IsDraw,初始值為False。 (2)我們需要把在函數func1中繪制的點保存在一個數組里,我是在Doc類下新建了一個數組空間。 (3)當自己寫的繪制函數執行完畢后,所有要重繪的點數據也全部存到數組中了,這里把IsDraw賦值為TRUE (4)然后在OnDraw函數中開始重繪,重繪內容就是func1中畫的東西,只不過這次我們要從Doc里的數組調取數據而已。因為如果不執行func1,Ondraw是沒的可畫的,所以在重繪前還要加上if判斷,如果IsDraw==TRUE,則執行重繪。
8.C語言取整問題 (1)向下取整 直接強制轉換。如int i = 2.5 ?, i=2 (2)向上取整 函數ceil 。 如 int i = ceil(2.5) ,i=3 ? 9.C語言txt文件讀取操作 (1)打開 ??? FILE *fp; ?? fp = fopen("E:\\.txt","r"); ? if(!fp)//容錯 ? { ??????? printf("ERROR");?? return 0; ? } (2)讀取——非循環 只讀一個數值 ? fscanf(fp,"%d",&N); (3)讀取——循環 讀一組數存入數組 for(i=0;i<N;i++) { ??????fscanf(fp."%d",&a[i]);?? //讀取浮點數一定要用 %lf 不要用%f 原因:http://blog.csdn.net/lutx/article/details/5072043 } ???? (4)寫文件 ? ?mkdir("E:\\STU");??????????????????????? //在硬盤新建文件夾和文件!!!
?fp2 = fopen("E:\\STU\\result.txt","w");
for(i=0;i<N;i++) { ????? fprintf(fp,"%d\t",result[i]); ? ????? if((i+1)%10 == 0) ????? { ??????????? fprintf(fp,"\n"); ????? } } (5)文件指針問題 ???? fgetc(fp); //可以使當前文件指針向后移動一位。在跳過空格 回車 很有用? ???? while(!feof(fp))//讀到文件末就停止 否則繼續讀 ? (6)fseek介紹 <整理并摘抄自百度百科> ? A.函數原型:int fseek(FILE *stream, long offset, int fromwhere); //負責文件指針操縱:如果執行成功則返回0(文件stream的內部指針以參數3為基準,偏移參數2的量),失敗返回-1 ? B.參數3可以有: (偏移起始位置:起始位置0(SEEK_SET),當前位置1(SEEK_CUR),文件尾2(SEEK_END)) ? C.主要作用:移動文件內部指針的位置,可以用來計算文件長度 ? 例子: 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; }
?(7)讀取字符串 ? A.fgetc函數:從文件中讀取一個字符,讀取一個字節后,光標位置后移一個字節。 ? 例子: 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++;}}
? B.fputc函數————將字符ch寫到文件指針fp所指向的文件的當前寫指針的位置。 例子: char msg[] = "Hello world"; int i = 0; //方法一while (msg[i]&&(i<strlen(msg))) { fputc(msg[i], fp1); i++; } //方法二fprintf(fp1,"%s",msg);
C.ctype.h —— 處理字符常用的頭文件 用例: //isalpha:檢查ch是否是字母 是字母則返回非0 否則返回0if(isalpha((int)ch))...//判斷ch是否為字母 char ch//isdigit:檢查ch是否為數字0-9 是則返回非0 否則返回0//islower:檢查是否為小寫字母//isupper:檢查是否為大寫字母//isalnum:檢查是否是字母或數字//ispunct:是否是標點字符//isspace:是否是空格符/跳格符/控制字符/換行符ch = tolower((int)ch);//大寫字母轉成小寫字母 ; toupper小寫轉大寫
D.fgets —— 讀取字符串 char *fgets(char *s, int n, FILE *stream); fgets函數的調用形式如下:fgets(str,n,fp); 此處,fp是文件指針;str是存放在字符串的起始地址;n是一個int類型變量。 函數的功能是從fp所指文件中讀入n-1個字符放入str為起始地址的空間內; 如果在未讀滿n-1個字符之時,已讀到一個換行符或一個EOF(文件結束標志),則結束本次讀操作,讀入的字符串中最后包含讀到的換行符。 因此,確切地說,調用fgets函數時,最多只能讀入n-1個字符。讀入結束后,系統將自動在最后加'\0',并以str作為函數值返回。 ? 通俗的講: 比如有文件 Hello world! Hello Hello world! 代碼為: int main() {FILE *fp1;fp1 = fopen("E:\\test.txt","r");char msg1[20];char msg2[20];fgets(msg1,4,fp1); //m=4fgets(msg2,7,fp1); //n=7printf("%s\n",msg1);printf("%s\n",msg2);return 0;}
情況一:(m=4 n=7) 輸出: Hel lo wor 情況二:(m=4,n=20)如果使用fgets() 讀取文件的時候bufsize大于該行的字符總數加2(多出來的兩個,一個保存文件本身的'\n'換行,一個保存字符串本身的結束標識'\0'),文件并不會繼續讀下去,僅僅只是這一行讀取完,隨后指向文件的指針會自動偏移至下一行。 Hel lo world! 情況三:(m=15,n=4) Hello world! Hel 情況四:(m=15,n=20) Hello world! ? Hello Hello world! (8)按行讀取數據<待續> ???? 10.C語言讀取raw ? ??//開始讀
?unsigned char *tmp = (unsigned char*)malloc(sizeof(unsigned char)*256*256);
?memset(tmp,0,sizeof(tmp));
?fread(tmp,sizeof(unsigned char),256*256,fp1); //格式轉換后再處理 int* data = (int*)malloc(sizeof(int)*256*256);
?memset(data,0,sizeof(data));
?for(i=0;i<=255*255;i++)
?{
??data[i] = (int)tmp[i];
?} //開始寫 fwrite(tmp,sizeof(unsigned char),256*256,fp2);? //tmp 為 unsigned char
?
總結
以上是生活随笔為你收集整理的自己在CODING过程中遇到的问题以及解决(C/VC)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】误差矩阵(混淆矩阵)评价法
- 下一篇: s3c2440移植MQTT