2016-11-25 33 views
0

首先,我已經使這個程序在一個cpp文件下工作得很好,但問題是將這個程序除以每個函數和頭文件 - 正如我的實驗室教師告訴在類中,我試圖將結構定義包含到頭文件中,但我不斷收到各種錯誤消息。我現在的頭文件的代碼如下:在頭文件中的結構定義中提出的字符串聲明

extern void threeLargest(Country countries[], Country fastGrowing[]); 
extern void readData(Country countries[]); 
extern void negGrowth(Country countries[]); 

const int MAXCOUNTRIES = 229; 
const int THREE = 3; 
struct Country { 
    string name; 
    double pop1950; 
    double pop1970; 
    double pop1990; 
    double pop2010; 
    double pop2015; 
    double growthRate; 
    }; 
struct World { 
    int numCountries; 
    Country countries[MAXCOUNTRIES]; 
    Country fastGrowing[THREE]; 
    } myWorld; 

現在,它給了我一個錯誤,說了這樣的(我只給他們帶來的一些,你會明白爲什麼):

In file included from lab10_0.cpp:1:0: 
lab10.h:6:2: error: ‘string’ does not name a type 
    string name; 
^
lab10_0.cpp: In function ‘void readData(Country*)’: 
lab10_0.cpp:17:37: error: ‘struct Country’ has no member named ‘name’ 
    getline(ifstr,myWorld.countries[i].name); 

它在我看來,頭文件不能識別字符串類型,其他使用頭的cpp文件也是如此。所以,我想包括

#include <string> 
using namespace std; 

在頭文件的開頭,但我得到一個完全不同的錯誤信息,說

/tmp/cclU6znx.o:(.bss+0x0): multiple definition of `myWorld' 
/tmp/ccQ69Fio.o:(.bss+0x0): first defined here 
/tmp/cckXoPSG.o:(.bss+0x0): multiple definition of `myWorld' 
/tmp/ccQ69Fio.o:(.bss+0x0): first defined here 
/tmp/cctaCWNQ.o:(.bss+0x0): multiple definition of `myWorld' 
/tmp/ccQ69Fio.o:(.bss+0x0): first defined here 
collect2: error: ld returned 1 exit status 

我以前做過這種分離的文件,但這次我必須在頭文件中包含結構定義,並且我在這裏沒有任何線索。請指教。實際上,我在Google上搜索時嘗試了很多很多事情,將頭文件分成兩部分,一個頭文件中的結構定義以及另一個文件中的函數,但仍然沒有運氣。

請指教。

p.s.如果需要,我可以發佈完整的程序。

============================================== ======================== 添加部分後多次會議和幫助來自我的朋友 我上傳原始cpp文件的代碼,我在開始時,想知道這可能會讓讀者更容易觀察我的問題。

#include <string> 
#include <iomanip> 
#include <iostream> 
#include <fstream> 


using namespace std; 

const int MAXCOUNTRIES = 229; 
const int THREE = 3; 

struct Country{ 
    string name; 
    double pop1950; 
    double pop1970; 
    double pop1990; 
    double pop2010; 
    double pop2015; 
    double growthRate; 
    }; 
struct World{ 
    int numCountries; 
    Country countries[MAXCOUNTRIES]; 
    Country fastGrowing[THREE]; 
    } myWorld; 

void threeLargest(Country countries[], Country fastGrowing[]); 
void readData(Country countries[]); 
void negGrowth(Country countries[]); 
int main() { 

readData(myWorld.countries); 
threeLargest(myWorld.countries,myWorld.fastGrowing); 
negGrowth(myWorld.countries); 

return 0; 
} 

void readData(Country countries[]) 
{ 

    fstream ifstr; 
    ifstr.open("population.csv"); 

    for (int i=0; !(ifstr.eof()) && i < MAXCOUNTRIES; i++) { 
    ifstr >> myWorld.countries[i].pop1950 >> myWorld.countries[i].pop1970 
       >> myWorld.countries[i].pop1990 >> myWorld.countries[i].pop2010 
       >> myWorld.countries[i].pop2015; 
    getline(ifstr,myWorld.countries[i].name); 
    myWorld.countries[i].growthRate = ((myWorld.countries[i].pop2015-myWorld.countries[i].pop1950)/myWorld.countries[i].pop1950)*100;} 

    ifstr.close(); 
} 

void threeLargest(Country countries[], Country fastGrowing[]) 
{ 
    myWorld.fastGrowing[THREE].growthRate = { }; 
    for (int i=0; i < MAXCOUNTRIES; i++) { 
     if (myWorld.countries[i].growthRate > myWorld.fastGrowing[0].growthRate) { 

      myWorld.fastGrowing[2].growthRate = myWorld.fastGrowing[1].growthRate; 
      myWorld.fastGrowing[2].name = myWorld.fastGrowing[1].name; 

      myWorld.fastGrowing[1].growthRate = myWorld.fastGrowing[0].growthRate; 
      myWorld.fastGrowing[1].name = myWorld.fastGrowing[0].name;  

      myWorld.fastGrowing[0].growthRate = myWorld.countries[i].growthRate; 
      myWorld.fastGrowing[0].name = myWorld.countries[i].name;} 

     else if (myWorld.countries[i].growthRate > myWorld.fastGrowing[1].growthRate) { 
      myWorld.fastGrowing[2].growthRate = myWorld.fastGrowing[1].growthRate; 
      myWorld.fastGrowing[2].name = myWorld.fastGrowing[1].name; 

      myWorld.fastGrowing[1].growthRate = myWorld.countries[i].growthRate; 
      myWorld.fastGrowing[1].name = myWorld.countries[i].name;} 

     else if (myWorld.countries[i].growthRate > myWorld.fastGrowing[2].growthRate) { 
      myWorld.fastGrowing[2].growthRate = myWorld.countries[i].growthRate; 
      myWorld.fastGrowing[2].name = myWorld.countries[i].name;} 
    } 


    cout << "The fastest growing country is " << myWorld.fastGrowing[0].name << ", which grew by " 
     << fixed << setprecision(2) << myWorld.fastGrowing[0].growthRate << "% between 1950 and 2015.\n" 

     << "The 2nd fastest growing country is " << myWorld.fastGrowing[1].name << " which grew by " 
     << fixed << setprecision(2) << myWorld.fastGrowing[1].growthRate << "% between 1950 and 2015.\n" 

     << "The 3rd fastest growing country is " << myWorld.fastGrowing[2].name << " which grew by " 
     << fixed << setprecision(2) << myWorld.fastGrowing[2].growthRate << "% between 1950 and 2015.\n"; 
} 

void negGrowth(Country countries[]) 
{ 
    cout << "The following countries' population shrunk between 1950 and 2015:" << endl; 
    for (int i=0; i < MAXCOUNTRIES; i++) { 
     if (myWorld.countries[i].growthRate < 0) 
     cout << myWorld.countries[i].name << " shrunk by " << fixed << setprecision(2) << myWorld.countries[i].growthRate << "%." << endl;} 
} 

=========================================== ============= 第二次編輯/我的頭文件看起來像下面這樣:

#ifndef LAB10_H 
#define LAB10_H 

#include <string> 

const int MAXCOUNTRIES = 229; 
const int THREE = 3; 

struct Country { 
    std::string name; 
    double pop1950; 
    double pop1970; 
    double pop1990; 
    double pop2010; 
    double pop2015; 
    double growthRate; 
    }; 

struct World { 
    int numCountries; 
    Country countries[MAXCOUNTRIES]; 
    Country fastGrowing[THREE]; 
}; 
extern World myWorld; 

extern void threeLargest(Country countries[], Country fastGrowing[]); 
extern void readData(Country countries[]); 
extern void negGrowth(Country countries[]); 

ENDIF

正如我在你們中的一些人的評論中提到,與extern World myWorld在頭文件中,我可以看到頭文件上的結構定義開始工作,但它讓我幾行錯誤說undefined reference to 'myWorld'。所以,我試着在所有的cpp文件中包含World myWorld(大多每個cpp文件都包含一個函數),最後我可以編譯這個程序。

然而,程序工作不正常 - 變量存儲不正確,沒有任何計算是正確的。

我的意思是,我沒有想到這個過程會很痛苦,讓我頭痛。

請指教:(

+1

誰告訴你「使用空間std對象;」 [不知道他在說什麼](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)。使用'std :: string'等... –

+0

@SamVarshavchik哦,那將是我,但仍然沒有運氣。我剛剛嘗試過。無論如何感謝:) – mjay

+0

嗯,你並沒有完全想到這一切。有人告訴過你這個指令,或者告訴你,這就是你對此的瞭解。不管是誰,他們都是錯的。正如鏈接中所解釋的,這是一種糟糕的編程習慣。 –

回答

1

的問題是,因爲編譯器指出,變量多的聲明。在頭文件,你只需要定義類型和宏,從不變量(與外部聲明除外) 。

在你的情況下,你定義了myWorld全局變量struct World類型。

struct World { 
    int numCountries; 
    Country countries[MAXCOUNTRIES]; 
    Country fastGrowing[THREE]; 
} myWorld; 

和我想象,在您的實現文件(的.cpp)你有這樣的:

#include "myheader.h" 
... 
World myWorld; 

發生了什麼事是,cpp預處理讀取每個CPP文件,並用替換文本#include "myheader.h"在真正編譯之前完成該文件的內容。這意味着,CPP編譯器看到,每個的.cpp,是這樣的:

struct World { 
    int numCountries; 
    Country countries[MAXCOUNTRIES]; 
    Country fastGrowing[THREE]; 
} myWorld; 
... 
World myWorld; 

現在你可以看到同一個變量的兩個聲明過,就像德CPP編譯器。

您需要刪除這些聲明中的一個,通常是標頭的聲明。

這是最糟糕的,當有很多文件.cpp包括相同的文件myheader.h,他們都將定義一個具有相同名稱的全局變量。

當您需要使用相同的全局變量在幾個.cpp文件,您可以在你的頭文件中的變量定義,而是用修改器extern,如:

struct World { 
    int numCountries; 
    Country countries[MAXCOUNTRIES]; 
    Country fastGrowing[THREE]; 
}; 
extern World myWorld; 

這將允許所有的.cpp文件知道變量myworld的存在。而且變量的實際定義只能在一個.cpp文件中,否則在鏈接階段會出現錯誤。

+0

哇..這是非常非常清楚的解釋頭文件。讓我解決一些問題,並儘快回覆 – mjay

+0

哇,所有的錯誤都消失了!認爲這個頭文件出現在每個cpp文件的前面,它不可能比這更簡單。 – mjay

+0

現在我有一些錯誤說'myWorld'沒有在這個範圍內從每個cpp文件中聲明。僅供參考,正如你所建議的那樣,我已經把「extern World myWorld」放進去了,這只是減少了大量的錯誤。 – mjay

0

你的頭文件中有一個include guard嗎?這將是這個樣子:

#ifndef LAB10_H 
#define LAB10_H 

// everything else goes in here 

#endif /* LAB10_H */ 

「LAB10_H」可以是所獨有的項目,所以按照慣例,它通常是大寫的文件名用下劃線代替點任意文本。

#ifndef LAB10_H 
#define LAB10_H 

#include <string> 

extern void threeLargest(Country countries[], Country fastGrowing[]); 
extern void readData(Country countries[]); 
extern void negGrowth(Country countries[]); 

const int MAXCOUNTRIES = 229; 
const int THREE = 3; 
struct Country { 
    std::string name; // avoiding "using namespace std;" 
    double pop1950; 
    double pop1970; 
    double pop1990; 
    double pop2010; 
    double pop2015; 
    double growthRate; 
}; 

struct World { 
    int numCountries; 
    Country countries[MAXCOUNTRIES]; 
    Country fastGrowing[THREE]; 
} myWorld;  

#endif /* LAB10_H * 
+0

有/無門衛,雖然 – mjay

+0

我仍然得到同樣的錯誤,但是你肯定還是希望每個頭文件都有防護。另一個答案是關於從World struct結尾刪除「myWorld」,用「extern World myWorld」取代它。在lab10.h和「世界我的世界」中在一個.cpp文件(可能是具有「main」功能的文件)中,應該這樣做... –

+0

我向每個cpp文件添加了'World myWorld',並且程序編譯時沒有錯誤,但程序沒有運行因爲它的意思是.. – mjay

0

隨着從該結構的末尾刪除「myWorld」,並加入「外部世界myWorld」的第一個答案,你需要在cpp文件的「一」與「世界myWorld」創建myWorld對象。

這裏是流量:

  1. 結構定義的.h
  2. 對象申報的.cpp
  3. 的extern在.H
+0

不知何故,即使在頭文件中包含'extern World myWorld',我也必須在每個cpp文件中包含'World myWorld',以免出錯。更糟糕的是,當我將'World myWorld'放入要編譯的程序的每個cpp文件中時,程序運行出錯 - 沒有任何變量存儲正確的值,並且沒有任何計算是正確的。 – mjay

+0

不,不要在每個cpp中放置「World myWorld」,但只需放入一個cpp文件。 –

相關問題