Kirjoittelen C++koodia Dev C++-työkalulla. Ohjelmani koostuu pääohjelmamoduulista, sekä kahdesta muusta moduulista. Muilla kuin pääohjelmamoduulilla on sekä määrittely- (.cpp) että otsikko- (.hpp) tiedosto.
Tekeekö tuo Dev C++ makefilen automaattisesti vai riittääkö useasta moduulista koostuvan ohjelman kääntämiseen pelkästään se, kun yrittää kääntää pääohjelmamoduulia.
Yritin kääntää pääohjelmamoduulia, mutta kääntämisyritys herjaa pääohjelmamoduulissa olevista muiden moduulien otsikkotiedostojen mainitsemisista, joista esimerkkinä toisen moduulin otsikkotiedoston maininta:
#include "tokamoduuli.hpp"
tokamoduulissa lukee:
#ifndef "TOKAMODUULI_HPP"
ja siitä tuli virheilmoitus: "macro names must be identifiers"
Mistä kiikastaa?
En ole paljoa koodannut c++:ssalla mutta eikös siitä "TOKAMODUULI_HPP" kohdasta pidä ottaa lainausmerkit pois.
Joo nuo hipsut tosiaan olivat liikaa, joten kiitti avusta. Olisi kyllä pitänyt itsekin tuo huomata.
Ohjelma ei kyllä vieläkään mene kääntäjästä läpi. En ymmärrä, että mikä mättää. Yritän tehdä ohjelmaa, joka lukee käyttäjän ilmoittamasta tiedostosta sanat ja niiden esiintymiskerrat map-rakenteeseen ja lisää ne sitten toiseen käyttäjän ilmoittamaan tiedostoon. Osaisin kyllä tehdä ohjelman, jos se koostuisi vain yhdestä moduulista, mutta haluan kokeilla useasta moduulista koostuvan ohjelman tekoa tuolla Dev c++:lla.
Kun pääohjelmaa yrittää kääntää, tulee seuraavat virheilmoitukset (3 kpl):
[Linker error] undefined reference to `Lue_Tiedosto(std::istream&, std::map<std::string, int, std::less<std::string>, std::allocator<std::pair<std::string const, int> > >&)' [Linker error] undefined reference to `Lisaa_Tiedostoon(std::ostream&, std::map<std::string, int, std::less<std::string>, std::allocator<std::pair<std::string const, int> > > const&, std::string const&)' ld returned 1 exit status
Ohjelma näyttää tällä hetkellä tältä:
pääohjelmamoduuli:
// // 27.12.2012 // #include <iostream> #include <string> #include <fstream> #include <map> #include <cstdio> using namespace std; #include "tiedostonluku.hpp" #include "tiedostoonkirjoitus.hpp" int main() { while(true){ string syote_01 = ""; cout << "Anna avattavan tiedoston nimi tai syota \"lopeta\": "; getline(cin, syote_01); if(syote_01 == "lopeta") { break; } ifstream avattava_tied(syote_01.c_str()); if(!avattava_tied) { cerr << "Tiedostoa '" << syote_01 << "' ei saa avattua!" << endl; continue; } map<string, int> sana_mappi; if(!Lue_Tiedosto(avattava_tied, sana_mappi)) { cerr << "Tiedoston kasittelyssa tapahtui virhe!" << endl; continue; } string syote_02 = ""; cout << "Anna tulostiedoston nimi: "; getline(cin, syote_02); ofstream tulos_tied(syote_02.c_str()); if(!tulos_tied) { cerr << "Tiedostoa '" << syote_02 << "' ei saa avattua!" << endl; continue; } if(!Lisaa_Tiedostoon(tulos_tied, sana_mappi, syote_01)) { cerr << "Tiedoston '" << syote_02 << "' kasittelyssa"; cerr << " tapahtui virhe." << endl; continue; } avattava_tied.close(); tulos_tied.close(); continue; } return EXIT_SUCCESS; }
toisen moduulin otsikkotiedosto:
// // Tiedostosta lukemisen ja mappiin lisäämisen hoitavan moduulin // otsikkotiedosto. #ifndef TIEDOSTONLUKU_HPP #define TIEDOSTONLUKU_HPP #include <iostream> #include <map> #include <string> #include <cstdio> using namespace std; bool Lue_Tiedosto(istream& virta, map<string, int>& mappi); #endif
toisen moduulin määrittelytiedosto:
// // Tiedostosta lukemisen ja mappiin lisäämisen hoitavan moduulin // määrittelytiedosto. #include <iostream> #include <map> #include <string> #include <cstdio> using namespace std; #include "tiedostonluku.hpp" bool Lue_Tiedosto(istream& virta, map<string, int>& mappi) { while(virta.peek() != EOF) { string sana = ""; virta >> sana; map<string, int>::iterator iter = mappi.begin(); while(iter != mappi.end()) { if(iter->first == sana) { int lkm = iter->second; lkm = lkm + 1; mappi[sana] = lkm; break; } ++iter; } if(iter == mappi.end()) { mappi[sana] = 1; } } if(!virta.eof()) { return false; } return true; }
kolmannen moduulin otsikkotiedosto:
// // Mapista lukemisen ja tiedostoon kirjoittamisen hoitavan moduulin // otsikkotiedosto. #ifndef TIEDOSTOONKIRJOITUS_HPP #define TIEDOSTOONKIRJOITUS_HPP #include <iostream> #include <string> #include <map> using namespace std; bool Lisaa_Tiedostoon(ostream& virta, const map<string, int>& mappi, const string& nimi); #endif
kolmannen moduulin määrittelytiedosto:
// // Mapista lukemisen ja tiedostoon kirjoittamisen hoitavan moduulin // määrittelytiedosto. #include <iostream> #include <string> #include <map> using namespace std; #include "tiedostoonkirjoitus.hpp" bool Lisaa_Tiedostoon(ostream& virta, const map<string, int>& mappi, const string& nimi) { virta << "Tiedoston '" << nimi << "' sisaltamat sanat ja niiden esiinty"; virta << "miskerrat:" << endl << endl; map<string, int>::const_iterator c_iter = mappi.begin(); while(c_iter != mappi.end()) { virta << iter->first; int sanan_pituus = iter->second.length(); int paljonko_tyhjaa = 22 - sanan_pituus; int i = 0; while(i < paljonko_tyhjaa) { virta << " "; ++i; } virta << ": " << iter->second << endl; ++c_iter; } if(!virta) { return false; } return true; }
Mod. lisäsi kooditagit!
Näyttää vahvasti siltä, että et ole lisännyt kakkos- ja kolmosmoduulia projektiin. Tällöin "moduuleita" ei käännetä, joten linkkeri ei voi löytää niitä. Sinun pitää siis lisätä .cpp -tiedostot projektiin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.