組態(tài)注意事項: 下面說明了關(guān)于在C腳本中處理字符串時最重要的問題。必須考慮性能和穩(wěn)定性因素。在不一致時,內(nèi)存區(qū)可能被覆寫,從而使系統(tǒng)鎖死 。最壞的情況出現(xiàn)在字符指針。如果指針設(shè)計不當,內(nèi)存區(qū)可能被覆寫。下面是有關(guān)錯誤和正確組態(tài)的四個樣例。 沒有預(yù)留內(nèi)存區(qū): char *a; a=GetTagChar("Tag name"); strcat(a,"xyz"); //有一個連接到文本的指針“a” //沒有預(yù)留內(nèi)存區(qū)- 正確: 通過查詢有效的指針將字符串正確復(fù)制到預(yù)定義的緩沖器中(來自描述WinCC信息系統(tǒng)的樣例):
- char* pszValue = NULL;
- char szValue[101];
- pszValue = GetTagChar("Varname"); //讀標簽值并將其緩存到pszValue。/*如果返回一個有效值,將該函數(shù)返回值存入局部字符串szValue中。最多保存100個字符。*/
- if(pszValue !=NULL) //!=NULL是必須執(zhí)行的檢查 //以便保證沒有NULL指針提交
- {
- strncpy(szValue,pszValue,100); …
- }
- else
- {
- printf("Pointer invalid\r\n"); //使用了無效值
- }
- }
沒有預(yù)留足夠的內(nèi)存區(qū): 通常,由于預(yù)留的內(nèi)存區(qū)太小導(dǎo)致內(nèi)存被覆寫。在這些情況下,通常在C中進行字符串處理時,文本結(jié)尾的一個附加字符必須始終被保留。也就是說,必須要比被處理的文本長度多預(yù)留出一個字符。- 錯誤: char a[4]; strcpy(a,"1234"); //總是有4個字符被復(fù)制到一個4字符的數(shù)組中; // 錯誤:文本的結(jié)尾字符被遺漏
- 正確: char a[5]; //內(nèi)存區(qū)的大小必須 //總是比被復(fù)制的文本多一個字符 strcpy(a,"1234");
字符*作為項目函數(shù)的返回值無效: 如果在項目函數(shù)中返回“char*”,必須用“SysMalloc”預(yù)留相應(yīng)的內(nèi)存區(qū)。如果內(nèi)存區(qū)是通過字符…[x]預(yù)留的,像“錯誤”例子中所描述那樣,那么當 退出項目函數(shù)時內(nèi)存區(qū)將立刻被釋放,因此在進行進一步的動作處理時將傳遞的是無效的值。- 錯誤:
- char* new_function_1()
- {
- char myString[100];
- sprintf(myString,"VarName%d", GetTagWord("processvariable"));
- return myString;
- }
- 正確:
- char* new_function_1()
- {
- char* myString;
- myString = SysMalloc(100);
- sprintf(myString,"VarName%d", GetTagWord("processvariable"));
- return myString;
- }
沒有Null指針檢索的無效字符串拷貝(導(dǎo)致日志文件 - WinCC_Sys_xx.LOG中的“ExecuteError in Action” ) 當動作在執(zhí)行并且圖像被取消選定(目標未發(fā)現(xiàn))時此條目出現(xiàn)在WinCC_Sys.Log中- 錯誤:
- char sign[5];
- strcpy(sign,GetText(lpszPictureName,lpszObjectName));
- if (0==strcmp(sign,"+"))
- {
- SetText(lpszPictureName,lpszObjectName,"-");
- SetVisible(lpszPictureName,"B5",TRUE);
- }
- else
- {
- SetText(lpszPictureName,lpszObjectName,"+");
- SetVisible(lpszPictureName,"B5",FALSE);
- }
為了避免無意的復(fù)制太多的字符到“sign” (例如在后來作改動時) ,并為了避免當取消選定圖像時由于“strcpy()”導(dǎo)致的異常,在“strncpy()”復(fù)制到Null-指針之前應(yīng)該使用和檢查“strncpy()” 。 - 正確:
- char sign[5], *myPointer;
- myPointer = GetText(lpszPictureName,lpszObjectName);
- if(myPointer != NULL)
- {
- strncpy(sign, myPointer, 4);
- if (0==strcmp(sign,"+"))
- {
- SetText(lpszPictureName,lpszObjectName,"-");
- SetVisible(lpszPictureName,"B5",TRUE);
- }
- else
- {
- SetText(lpszPictureName,lpszObjectName,"+");
- SetVisible(lpszPictureName,"B5",FALSE);
- }
- }
- else
- {
- printf("Error in GetText() !\r\n");
- }
警告: 函數(shù)strcpy()將“Source”指針所指向的包含末尾字符'\0’的字符串復(fù)制到“Target”指針指向的位置。字符串不能 重疊,并且目標必須足夠大 (源字符串長度 + 1,因為有'\0’)。函數(shù)strncpy()除了僅復(fù)制起始的n個字節(jié)外其余與函數(shù)strcpy()相同。如果起始的n個字節(jié)中沒有'\0’,結(jié)果將不是以'\0’結(jié)束。這將導(dǎo)致未定義的系統(tǒng)狀態(tài)。
用strcat函數(shù)來連接字符串。 假設(shè)有四個變量tag1,tag2,tag3,tag4都是8位文本字符變量。把tag1~tag3連接起來顯示在tag4中。測試:先建立這四個變量,然后在wincc的畫面中建立四個輸入輸出域,分別連接tag1~tag4,建立一個按鈕,在按鈕的c動作中: char buffer[256]=""; strcat(buffer,GetTagChar("tag1")); strcat(buffer,GetTagChar("tag2")); strcat(buffer,GetTagChar("tag3")); SetTagChar("tag4",buffer);
|