2014-09-02 62 views
0

我試圖讀取';'分隔的數據,成爲一個結構數組,所以我可以稍後過濾它們。 示例數據:將分區數據讀入數組結構C++

1.1 ; name1; 11-07-2014; 14:30 
1.2 ; name2; 11-07-2017; 15:10 

我不知道有多少項目會在此.txt文件。此外,我需要添加一個posibility來選擇用戶想要工作的文件(那有效)我是新的C++,所以我會爲任何提示gratefull。

到目前爲止,我已經創造了這個:

typedef struct{ 
    char numb[21]; 
    char names[100]; 
    char date[11]; 
    char time[6]; 
}vec; 

vec *logs[200]; 

void_fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    OPENFILENAME ofn; 
    char fname[MAX_PATH] =""; 
    ZeroMemory(& ofn, sizeof(ofn)); 
    ofn.lStructSize = sizeof(ofn); 
    ofn.lpstrFilter = "Text files (*.txt)\0*.txt\0All files\0*.*\0"; 
    ofn.nMaxFile = MAX_PATH; 
    ofn.lpstrFile = fname; 
    ofn.lpstrDefExt = "txt"; 
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; 

    string line; 

    if(GetOpenFileName(& ofn)) 
    { 
     for(int i=0; i<200; i++){ 
      getline(fname, logs[i].numb, ';'); 
      getline(fname, logs[i].names, ';'); 
      getline(fname, logs[i].date, ';'); 
      getline(fname, logs[i].time, ';'); 
     } 
    } 
} 

我得到這個錯誤 E2285找不到 '函數getline < _CharT,_Traits,_Alloc>(字符*,不確定的,字符)'

匹配
+0

使用getline讀取整行。然後,在該行內找到分號。 – 2014-09-02 11:31:23

+0

'logs'是一個'vec *'數組,但你沒有使用正確的操作符。你應該使用'logs [i] - >麻木'。其次,你錯誤地使用了'std :: getline'(假設它就是這個樣子)。沒有重載將'char []'作爲第一個參數。 – 2014-09-02 11:35:21

回答

0

我對你的代碼感到困惑。 fname是一個LPTSTR,所以是一個字符串。這應該如何與getline一起工作?

的只得到線的功能,我知道有兩種情況:

ssize_t getline(char **lineptr, size_t *n, FILE *stream); 
ssize_t getdelim(char **lineptr, size_t *n, int delim, FILE *stream); 

或:

std::istream& std::getline(std::istream& is, std::string& str, char delim); 
std::istream& std::getline(std::istream& is, std::string& str); 

而且由於你使用GetOpenFileName你在使用Windows,這意味着你只能使用更高版本。無論如何,你需要真正打開一個文件閱讀。

如何:

struct vec{ 
    std::string numb; 
    std::string names; 
    std::string date; 
    std::string time; 
}; 

std::vector<vec> logs; 

size_t i = 0; 
std::ifstream in(fname); 
while (in.good() && i < 200) 
{ 
    std::string line; 
    getline(in, line); 

    std::vector<std::string> bits = explode(line, ";"); 
    assert(bits.size() == 4); 
    vec v = {bits[0], bits[1], bits[2], bits[3]}; 
    logs.push_back(v);   
    i++; 
} 

這裏是我的得心應手爆炸功能:

std::vector<std::string> explode(const std::string& str, const std::string& delimiter) 
{ 
    std::vector<std::string> gibs; 
    size_t start = 0; 
    size_t end = 0; 

    while ((start != std::string::npos) && (start < str.size())) 
    { 
     end = str.find(delimiter, start); 

     std::string gib; 
     if (end == std::string::npos) 
     { 
      gib = str.substr(start); 
      start = std::string::npos; 
     } 
     else 
     { 
      gib = str.substr(start, end - start); 
      start = end + delimiter.size(); 
     } 
     gibs.push_back(gib); 
    } 

    return gibs; 
} 

最後讓你的心,如果你想編寫C或C++。混合兩者從來都不是一個好主意。

+0

非常感謝。我還有一個問題。有一個錯誤,我不能在一行中解決: logs.push_back({bits [0],bits [1],bits [2],bits [3]}); 我知道這行是添加新元素所必需的,但是程序只有在我發表評論時纔會編譯。 – 2014-09-02 14:33:53

+0

是的,這是正確的,那裏的代碼是錯誤的。你不能在函數調用中建立一個「inline」結構。我通過顯式構建結構並將其添加到向量來修復代碼。 – rioki 2014-09-03 08:05:23

+0

我試過這種方法(首先將{}改爲{}),但仍然存在錯誤:無法將'string'轉換爲'vec'。 – 2014-09-03 10:59:02