2017-04-26 39 views
0

我需要實現在C遞歸函數,可以模擬一個pstree,就是想象中的數字下面的過程:不完整的C遞歸函數。我不知道如何實現正確

1 (father) 
   2 (child of 1) 
   3 (child of 1) 
     4 (son of 3) 
       5 (child of 4) 
     6 (child of 3) 

等....

void imprime_Pstree(int i, int ntabs) 
{ 
    int k = 0, j = 0, quantProc = 0; 
    int procAtual; 

    // Prints the number of tabs 
    for(k = 0; k < ntabs; k++) 
     printf("\t"); 

    quantProc = preenche_vetor(i); 

    // Prints the process name 
    imprimeNomeProcesso(i); 


    for(j = 0; j < quantProc; j++) { 

     imprime_Pstree(processos[j], ntabs+1); 
    } 

} 

但它只打印父(稱爲遞歸函數)和相同的孩子,誰沒有其他孩子。 我知道另一個對遞歸函數的調用在前一個子項的父項中丟失,但是怎麼做?


全碼:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <string.h> 

int processos[1000]; 

void limpa_vetor() { 
    int i; 
    for(i = 0; i < 1000; i++) 
     processos[i] = 0; 
} 

int preenche_vetor(int proc) { 
    char path[50]; 
    char string[100]; 
    int i, j = 0, cont = 0; 
    char temp; 
    FILE *arq; 

    limpa_vetor(); 

    sprintf(path, "/proc/%d/task/%d/children", proc, proc); 
    arq = fopen(path, "r"); 

    if (arq != NULL) 
    { 
     limpa_vetor(); 

     fscanf(arq, "%s", string); 
     while(strcmp(string, "") != 0) 
     { 
      if(feof(arq)) break; 
      processos[j] = atoi(string); 
      cont++; 

      fscanf(arq, "%c", &temp); 
      fscanf(arq, "%s", string); 
      j++; 
     } 
    } 
    return cont; 
} 

void imprimeNomeProcesso(int proc) { 
    char path[50]; 
    char string[100]; 
    int i, j = 0; 
    char temp; 
    FILE *arq; 

    sprintf(path, "/proc/%d/stat", proc); 
    arq = fopen(path, "r"); 

    if (arq != NULL) 
    { 
     fscanf(arq, "%s", string); 
     while(strcmp(string, "") != 0) 
     { 
      if(feof(arq)) break; 

      if(j == 1) 
      { 
       printf("%s ", string); 
       break; 
      } 

      fscanf(arq, "%c", &temp); 
      fscanf(arq, "%s", string); 
      j++; 
     } 
     printf("\n"); 
    } 

} 

void imprime_Pstree(int i, int ntabs) 
{ 
    int k = 0, j = 0, quantProc = 0; 
    int procAtual; 

    // Imprime a quantidade de tabs 
    for(k = 0; k < ntabs; k++) 
     printf("\t"); 

    quantProc = preenche_vetor(i); 

    // Imprime o nome do processo 
    imprimeNomeProcesso(i); 


    for(j = 0; j < quantProc; j++) { 

     imprime_Pstree(processos[j], ntabs+1); 
    } 

} 

int main() 
{ 
    imprime_Pstree(1, 0); 

    return 0; 
} 
+0

似乎'processos'是一個全局變量,它包含'i'的所有子元素的列表。這在遞歸函數中不起作用。遞歸調用將覆蓋數組。您必須將其設置爲本地變量並將其傳遞給需要分配值的函數 –

回答

0

processos是一個全局變量,它包含我的所有孩子的名單。這在遞歸函數中不起作用。遞歸調用將覆蓋數組。你必須讓一個局部變量並把它傳遞到具有分配的值的函數:

void imprime_Pstree(int i, int ntabs) 
{ 
    int k = 0, j = 0, quantProc = 0; 
    int procAtual; 
    int processos[1000]; // <-- have a local array 

    // Imprime a quantidade de tabs 
    for(k = 0; k < ntabs; k++) 
     printf("\t"); 

    // pass that array to preenche_vetor() 
    quantProc = preenche_vetor(i, processos); 

    // Imprime o nome do processo 
    imprimeNomeProcesso(i); 


    for(j = 0; j < quantProc; j++) { 

     imprime_Pstree(processos[j], ntabs+1); 
    } 

} 

當然,你也必須改變preenche_vetor()的簽名,必須執行初始化()那裏。

編輯 作爲@Aconcagua公頃建議,它甚至會更好,首先要確定孩子的數量,然後申報,並填寫一VLA

+0

在這種情況下,固定大小的數組給我帶來不好的感覺 - 要麼他們太大,要麼他們不能滿足需求。我個人更喜歡吸氣劑的兒童進程的數量,並使用這一個來初始化VLA ... – Aconcagua

+0

@Aconcagua是的,你是一個改進。我只是想盡可能少地指出實際問題的核心 –

0
quantProc = preenche_vetor(i); 

好了,現在我們有一些進程。

for(j = 0; j < quantProc; j++) 
{ 
    imprime_Pstree(processos[j], ntabs+1); 
} 

兩種可能的情況:

  1. processos包含一個列表系統中的所有活動的進程。然後你會像在數組中發現的那樣迭代這些進程。即如果任何進程至少有一個子進程,則系統中的第一個進程(linux:將是id爲0的進程,通常不會死)始終會作爲當前進程的子進程打印。您需要一個包含您可以迭代的子進程id的單獨列表!

  2. processospreenche_vetor函數填充子進程爲給定進程ID。然後,任何遞歸調用imprime_Pstree將覆蓋被調用者的子進程列表(因爲preenche_vetor被再次調用)。解決方案:您需要爲每個遞歸調用提供一個單獨的數組。

相關問題