2014-07-21 64 views
0

我需要幫助,對我來說這似乎是一個神祕的問題,我看不到如何解決它。當從cygwin調用時,C++ exe將不同的文本輸出寫入文件

我已經寫了一個C++ exe。它具有讀取包含一些線,如小的文本文件非常簡單的任務:

house <CLASSMISSING> missing  
roof <CLASSMAJORWEAR> major wear 

做標籤上的一番比較,寫的很簡單的結果(文本)爲.csv文件。 的輸出如下所示:

house 11; MISSING 

這個輸出是由製備:

fout << argv[3] << ";" << sC_damages.get_damage(sC_damages.worst_dam_ID).c_str() << "\n"; 

其中的argv [3]在這種情況下「房屋11」傳遞給程序的命令的識別符的字符串在這種情況下sC_damages.get_damage會輸出一個字符串「MISSING」。 結果寫入通過以下方式追加模式打開的文件:

ofstream fout(argv[2], ios::app); 

當我運行這個從CMD(Win7的),或者出的Visual Studio 2010,一切都很好。然而我需要/想從cygwin下的bash腳本運行它。

當我調用C++程序從一個cygwin32 bash命令行數次:

cygdrive/d/CCpp/program.exe "out_tmp//house11.txt" houses.csv "house 11" 

再看看在輸出文件houses.csv結果(對於每個相同的命令行調用相同的結果應附加)我得到以下災難:

house 11;MISSING 
house 11;MISSING 
house 11;™ 
ï2åK¨vhouse 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11òëc‰çÁu*Ihouse 11;MISSING 

所以時不時神祕字符inserted.There沒有爲它的模式。 從CMD調用時相同的輸出看上去很完美:

house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 
house 11;MISSING 

我實在無法理解的ofstream如何(這是我在C++程序中使用寫入文件houses.csv)產生當程序被調用不同的輸出從CMD或從cygwin bash。

請幫忙!

P.S.

的代碼如下:

#include <fstream> 
#include <iostream> 
#include "damageClass.h" 

using namespace std; 

int main(int argc, char **argv) 
{ 
    char ch; 
    int dam_ID = 0; 
    int dam_ID_tmp = 0; 
    char sc_damage[80]; 
    char dump[256]; 
    string uT_Tag; 
    string source = argv[3]; 


    damages sC_damages; 
    sC_damages.reset(); 

    //check correct number command line arguments 
    if (argc != 4) 
    { 
     cout << "Usage: " << argv[0] << "<input concord.txt filename> <output csvfilename> <reportfilename> " << endl; 
     return(1); 
    } 


    //input concord.txt file 
    ifstream fin(argv[1]); 

    //outputcsv file 
    ofstream fout(argv[2], ios::app); 
    if (!fout) 
    { 
     cout << "Unable to open " << argv[2] << " in append mode.\n"; 
     return (1); 
    } 

    while (!fin.eof()) 
    { 
     while (fin.get(ch)) 
     { 

      uT_Tag = ""; 
      if (ch == '<') //if line in concord.txt starts with < 
       fin.putback('<'); 

      //read out damage tag from in between <> 
      if (fin.peek() == '<') 
      { 
       fin.ignore(1, '<'); 
       fin.getline(sc_damage, 80, '>'); 
       fin.getline(dump, 256); 
       uT_Tag = sc_damage; 
       int weight = sC_damages.get_dam_weight(uT_Tag); // weight= only for debug output. Class call necessary to compute worst_dam_ID 
       break; 
      } 
     } 
    } 

    cout << "writing: " << argv[3] << "; " << sC_damages.get_damage(sC_damages.worst_dam_ID) << endl; 
    fout << argv[3] << ";" << sC_damages.get_damage(sC_damages.worst_dam_ID).c_str() << "\n"; 

    fout.close(); 
    fin.close(); 
    return 0; 
} 

這是類的定義:

#include "damageClass.h" 

//const char *damageTags[5] = { "CLASSOK", "CLASSMINORWEAR", "CLASSMAJORWEAR", "CLASSBROKEN", "CLASSMISSING"}; 
//const char *damages[5] = { "NODAMAGE", "MINORWEAR", "MAJORWEAR", "BROKEN", "MISSING"}; 

damages::damages() 
{ 
    this->damageClasses.clear(); 

    damageClass dC; 
    dC.m_damageTag = ""; 
    dC.m_damage = "NOFINDING"; 
    dC.dam_weight = 0; 
    this->damageClasses.push_back(dC); 

    dC.m_damageTag = "CLASSOK"; 
    dC.m_damage = "NODAMAGE"; 
    dC.dam_weight = 1; 
    this->damageClasses.push_back(dC); 

    dC.m_damageTag = "CLASSMINORWEAR"; 
    dC.m_damage = "MINORWEAR"; 
    dC.dam_weight = 2; 
    this->damageClasses.push_back(dC); 

    dC.m_damageTag = "CLASSMAJORWEAR"; 
    dC.m_damage = "MAJORWEAR"; 
    dC.dam_weight = 3; 
    this->damageClasses.push_back(dC); 

    dC.m_damageTag = "CLASSBROKEN"; 
    dC.m_damage = "BROKEN"; 
    dC.dam_weight = 4; 
    this->damageClasses.push_back(dC); 

    dC.m_damageTag = "CLASSMISSING"; 
    dC.m_damage = "MISSING"; 
    dC.dam_weight = 5; 
    this->damageClasses.push_back(dC); 
} 

damages::~damages() 
{ 
    this->damageClasses.clear(); 
} 

int damages::get_dam_weight(string UT_damageTag) 
{ 
    for (unsigned int i = 0; i < this->damageClasses.size(); i++) 
    { 
     damageClass dC = this->damageClasses.at(i); 
     if (dC.m_damageTag == UT_damageTag) 
     { 
      this->worst_dam_ID = max(dC.dam_weight, this->worst_dam_ID); 
      return dC.dam_weight; 
     } 
    } 
    return 0; 
} 

string damages::get_damage(int dam_weight) 
{ 
    for (unsigned int i = 0; i < this->damageClasses.size(); i++) 
    { 
     damageClass dC = this->damageClasses.at(i); 
     if (dC.dam_weight == dam_weight) 
     { 
      return dC.m_damage; 
     } 
    } 
    return "ERROR: no matching damage class"; 
} 

void damages::reset() 
{ 
    this->worst_dam_ID = 0; 
} 

和類此聲明:

#include <string> 
#include <vector> 

using namespace std; 


//class description 
class damageClass 
{ 
public: 
    //attributes 
    string m_damageTag; 
    string m_damage; 
    int dam_weight; 
}; 


class damages 
{ 
public: 
    damages(void); 
    ~damages(void); 

    //attributes 
    vector<damageClass> damageClasses; 
    int worst_dam_ID; 

    //methods 
    int get_dam_weight(string UT_damageTag); 
    string get_damage(int dam_weight); 
    void reset(); 
}; 
+0

看起來像未定義的行爲。除非您向我們展示一些實際代碼,否則我們可以告訴**沒有任何** –

+0

所以它看起來像argv [3]正在失去終止空。所以在某個地方,代碼會破壞內存。您可能需要使用調試器,並在每行觀察argv [3]的結果,並查看它何時更改。使用std :: string是一個好主意,因爲固定長度的char數組很麻煩。我可能會首先更改sc_damange並將其轉儲爲字符串,並使用std :: getline而不是fin.getline,因爲這樣更安全。 –

+0

非常感謝我會嘗試你的建議。我已經做的就是放棄argv [3]輸出。我甚至只是像「xxxxxxx」那樣定義了一個字符串,並將其作爲唯一的輸出。所以沒有其他輸出比在程序中定義的字符串,仍然我得到了這種效果(我已經無法相信這一點了,雖然我認爲我做了正確的)。在嘗試了很多之後,剩下的唯一一件事似乎是,來自cygwin的調用導致了不同於來自cmd的調用的行爲。 – user3010324

回答

0

對,這是一個困難的。我正在使用SafeGuard LanCrypt。顯然,當在Cygwin隨機符號下追加文件時會產生。 寫入未加密的共享可解決此問題。