簡體   English   中英

在 while 循環中多次調用 function

[英]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只刪除一些字符,所以它可以就地執行此操作。 因此,根本不需要strlenmalloc 見下文...


您的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM