與C++

2013-09-23 21 views
-3

更改文件內容請看下面的文件內容與C++

[channels] 
usecallerid=yes 
cidsignalling=dtmf 
cidstart=dtmf 


;group=0 
usecallerid=yes 
context=pstn-channels 
channel=>5 

;group=0 
usecallerid=yes 
context=pstn-channels 
channel=>6 

;group=0 
usecallerid=yes 
context=pstn-channels 
channel=>7 

;group=1 
context=phone-channels 
channel=>1-4 

我只是想用C搜索頻道的改變信道的一些性質++。重點是每個頻道的屬性都寫在「頻道」關鍵字的上方。 例如,我需要將頻道5的上下文屬性更改爲電話。 我該怎麼做?

編輯:

所以我終於找到了一種方法。我一行一行地讀取文件,尋找「group」關鍵字,在到達這個關鍵字後,我開始推回每一行到一個字符串向量,直到我到達包含「channel」關鍵字的行。然後我用「=」分隔符分隔最後一行,並將單元格編號1與「portNumber」進行比較,如果它們匹配,我搜索字符串向量(以「group」開頭並以「channel」關鍵字結尾的數據塊)對於用戶想要改變它的屬性,在找到這個屬性後,我計算出適當的偏移量,用seekg函數改變文件的指針位置,然後寫入數據。 但是,每行都有一定數量的字符,即當插入較長的行時,其他行會錯過。考慮塊以下

;group=0 
usecallerid=yes 
context=pstn-channels 
channel=>131 

第三行,如果我想改變這行像「上下文=電話通道」,其結果將是

;group=0 
usecallerid=n 
context=phone-channels 
channel=>130 

,你可以看到第二行得到錯誤的價值。我認爲在編輯之前在每一行的末尾添加一些空格是有用的,它可以工作,但我認爲這不是一個有效的解決方案。所以你怎麼看?我希望這個問題和問題對你來說很清楚。

而這裏的代碼

bool changeConfigFiles(string addr, int portNumber, string key, string value) 
{ 
    // 
    char cmd[200]; 
    fstream targetFile(addr.c_str()); 
    string lines; 
    int offset=0,pPosition; 
    vector<string> helper,anotherHelper; 
    vector<string> contentsBlock; 
    // 
    if (!targetFile.is_open()) 
    { 
     return false; 
    } 
    // 
    while(getline(targetFile, lines)) 
    { 
     if(lines.find("group") != string::npos) 
     { 
      pPosition = targetFile.tellg(); 
      pPosition -= lines.length(); 
      contentsBlock.push_back(lines); 
      while(getline(targetFile, lines)) 
      { 
       if(lines.find("=>") != string::npos) 
       { 
        helper = explode("=>",lines); 
        contentsBlock.push_back(lines); 
        break; 
       } 
       contentsBlock.push_back(lines); 
      } 
     } 
     // 
     if(helper.size() !=0 && strToInt(helper[1]) == portNumber) 
     { 
      for(int i=0;i<contentsBlock.size();i++) 
      { 
       if(contentsBlock[i].find(key) != string::npos) 
       { 
        anotherHelper = explode("=",contentsBlock[i]); 
        targetFile.seekg(pPosition+offset-1); 
        targetFile << endl << anotherHelper[0] << "=" << value << endl; 
       } 
       offset += contentsBlock[i].length(); 
      } 
      // 
      helper.clear(); 
      targetFile.seekg(pPosition+offset); 
     } 
    contentsBlock.clear(); 
    } 
    targetFile.close(); 
    return true; 
} 
+0

我修正了你的標籤。由於您使用C++編碼,因此不要標記問題C. –

+4

這看起來像一個INI文件。所以,得到一個INI文件解析器。 Boost有一個。 –

+1

如果你展示你迄今爲止已經嘗試過的東西,那麼你將有更好的運氣得到答案,因爲SO不是代碼寫作服務...... –

回答

0

假設你有一個已知的數據佈局這個文件,我要回答這個問題,就好像它是一個「我怎麼分析這個文件」的問題。在C++中,fstream是本地解析文件的一種簡單方法。考慮以下(假定你有一個字符串分割和一個字符串的IndexOf方法,這兩者都是相當瑣碎寫):

char** SplitString(_In_ char* string, _In_ char token, _Out_ int* tokenCount); 
int IndexOf(_In_ char* string, _In_ char* search, _Out_ int* count, _Out_ int length); 

CustomFileType* ParseFile(char* filename) 
{ 
    int bufferSize = 10000; 
    auto buffer = new char[ bufferSize]; 
    memset(buffer, 0, bufferSize); 

    ifstream file(filename); 

    file.read(buffer, bufferSize); 

    file.close(); 

    int blockCount = 0; 
    auto blocks = SplitString(buffer, ';', &blockCount); 

    CustomFileType* file = new CustomFileType(); 

    for(int blockIndex = 0; blockIndex < blockCount; blockIndex++) 
    { 
     Block* b = new Block(); 
     b.PropertyX = GetValueOf(buffer, "PropertyX="); 
     b.PropertyY = GetValueOf(buffer, "PropertyY="); 
     file.Blocks.Add(b);      
    } 
} 

char* GetValueOf(char* buffer, char* key) 
{ 
    int count = 0; 
    int length = 0; 
    int index = IndexOf(buffer, key, &count, &length); 

    if(length == 0 || count == 0) return nullptr; 

    auto output = new char[ length ]; 
    memcpy(output, &buffer[ index ], length); 
    return output; 
} 

,大約涵蓋解析的想法。將文件分解成塊,讀取每個塊的每個元素,檢索與每個鍵相關的每個值,轉換爲數據類型(上面未顯示)並分配給相關屬性。

要更改文件的值,您可以簡單地(我稱之爲)解開它,將數據結構重新轉換爲格式。因此,使用解析器讀取對象,更改值,然後解析它(或將其編碼,無論您選擇哪個術語)。

要更改值並將它們寫回文件,請考慮實際的問題。您已將文本解析爲一個對象,並知道文件格式。所以現在它是一個替換對象的值並將它們寫回到文件的問題。你的文件結構看起來像它遵循以下格式:

[頁眉信息]

[組]

當羣體之間用分號分隔,並且兩個頭信息和組通過集合定義鍵值對(x = y)。所以說,你需要一種方法,知道如何編寫鍵值對(這應該是微不足道的),然後是另一種方法,可以理解頭/組佈局,並可以接受一個對象(可能是CustomFileType,如前面的示例中所使用的) )並可以讀取該對象並將其值轉換爲您的文件格式。在沒有真正爲你寫分析器和作家的情況下,這可能是我能解釋它的最好方法。

+0

請參閱修改 –