[英]Calling a function too many times in a while loop
The function char** read(char file[])
is supposed to return an array of strings, and every string represents a Json object extracted from a json file.
char* Purge(char S[], int n)
從字符串(從 json 文件中提取)中刪除' '
(空格)、 '"'
、 ','
、 '\t'
。
主要問題是 while 循環中的第一條語句seBuffer = Purge(Buffer, strlen(Buffer) + 1);
它使用 Purge function 的方式太多次,對於已經檢查過的字符,它從一個 json object 的開始到結束的整個過程中發生,我應該擔心什么? 還是有另一種可能更有效的方法?
char** read(char file[])
{
FILE* pF = fopen(file, "r");
if(pF == NULL)
{
exit(EXIT_FAILURE);
}
char Buffer[MAX], oJson[MAX], c;
char* seBuffer;
int nbOJ = 0, toAllocate = 0;
while((c = fgetc(pF)) != EOF)
if(c == '{')
nbOJ++;
Size = nbOJ;
rewind(pF);
char** ObjectsJson = (char**)malloc(nbOJ*sizeof(char*));
nbOJ = -1;
while(fgets(Buffer, MAX, pF))
{
seBuffer = Purge(Buffer, strlen(Buffer) + 1);
if(seBuffer[0] == '[' || seBuffer[0] == ']')
continue;
if(seBuffer[0] == '{')
{
oJson[0] = 0;
nbOJ++;
continue;
}
if(seBuffer[0] == '}')
{
ObjectsJson[nbOJ] = (char*)malloc((toAllocate+1)*sizeof(char));
strcpy(ObjectsJson[nbOJ], oJson);
toAllocate = 0;
continue;
}
toAllocate += strlen(seBuffer);
sprintf(oJson, "%s%s", oJson, seBuffer);
}
free(seBuffer);
fclose(pF);
return ObjectsJson;
}
這是由頂級評論重新開始的。 就地修改和 memory 泄漏。
因為Purge
只刪除一些字符,所以它可以就地執行此操作。 因此,根本不需要strlen
或malloc
。 見下文...
您的Purge
代碼存在一些問題。
在下面的原始代碼中, Purge
的調用者執行strlen
並將其作為第二個參數傳遞。 然后Purge
執行自己的strlen
,覆蓋/丟棄調用者的值。
Purge
預掃描輸入字符串一次以獲取要刪除的字符數/計數。
這樣可以減少給予malloc
的數量。 但是,對於這個用例,只使用原始長度會更好,因為它節省了額外的掃描,這在很大程度上是一個很好的選擇。
但是,如果我們真的想在縮短的列表上使用malloc
並進行預掃描,則預掃描循環可以一次計算要刪除的字符數和字符串長度。 因此,所有單獨的strlen
調用都是多余的。
因此,在原始代碼中,字符串緩沖區一共被掃描了四次。
這是您的Purge
function 的原始代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *
Purge(char S[], int n)
{
// ETVG = Espace , tabulation, virgule, guillemet
int nbETVG = 0, j = 0;
n = strlen(S);
for (int i = 0; i < n; i++)
if (S[i] == ' ' || S[i] == '\t' || S[i] == ',' || S[i] == '"')
nbETVG++;
int m = n - nbETVG;
char *SE = (char *) malloc(m * sizeof(char));
for (int i = 0; i < n; i++) {
if (S[i] == ' ' || S[i] == '\t' || S[i] == ',' || S[i] == '"')
continue;
SE[j] = S[i];
j++;
}
return SE;
}
void
main()
{
char *Pstr;
char str[] = { "this , is a test ." };
Pstr = Purge(str, strlen(str));
printf("%s", Pstr);
}
這是重構的Purge
代碼:
#include <stdio.h>
void
Purge(char *src)
{
char *dst = src;
for (int chr = *src++; chr != 0; chr = *src++) {
switch (chr) {
case ' ':
case '\t':
case ',':
case '"':
break;
default:
*dst++ = chr;
break;
}
}
*dst = 0;
}
int
main(void)
{
char str[] = { "this , is a test ." };
printf("%s\n", str);
Purge(str);
printf("%s\n", str);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.