質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
g++

g++はGNUコンパイラコレクション(gcc)のC++コンパイラーです。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1292閲覧

C++コンパイル時のエラー

Kota.Y

総合スコア25

g++

g++はGNUコンパイラコレクション(gcc)のC++コンパイラーです。

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

コンパイルエラー

コンパイルのフェーズで生成されるエラーです。よく無効なシンタックスやタイプが含まれているとき発生します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/06/07 02:53

編集2020/06/07 03:05

hppファイルは1つ

hpp

1#pragma once 2#include <iostream> 3#include <vector> 4#include <string> 5#include <tuple> 6using namespace std; 7 8void insertNames(); 9void JCtoAC(string eraName, int eraNum); 10void ACtoJC(int inputNum); 11 12extern const int startYear; 13extern const int thisYear; 14 15vector<tuple<string, int>> names;

c++ファイルは3つ

cpp

1//era.cpp 2#include "era.hpp" 3 4int main() 5{ 6 JCtoAC("Reiwa", 1); 7}

cpp

1//names.cpp 2#include "era.hpp" 3 4const time_t now = time(nullptr); 5const tm *lt = localtime(&now); 6const int startYear = 1615 - 1; //明治元年なので1を引く 7const int thisYear = 2000 + lt->tm_year; 8const int reiwa = (thisYear - 100) - 2019 + 1; //元号のスタートは0年ではないため1を足す 9 10vector<string> erasNames = { 11 "Genna", "Kanei", "Shouhou", "Keiwan", "Jouou", "Meireki", "Manji", "Kanbun", "Enpou", "Tenna", "Joukyou", "Genroku", "Houei", 12 "Syoutoku", "Kyouhou", "Genbun", "Kanpou", "Enkyou", "Kanen", "Houreki", "Meiwa", "Anei", "Tenmei", "Kansei", "Kyouwa", "Bunka", 13 "Bunsei", "Tenpou", "Kouka", "Kaei", "Ansei", "Manei", "Bunkyuu", "Genji", "Keiou", "Meiji", "Taisyou", "Syouwa", "Heisei", "Reiwa"}; 14 15vector<int> erasYears = {10, 21, 5, 5, 4, 4, 4, 13, 9, 4, 5, 17, 8, 6, 21, 6, 4, 5, 4, 14, 9, 10, 9, 13, 4, 15, 13, 15, 5, 7, 7, 2, 4, 2, 4, 45, 15, 64, 31, reiwa}; 16 17void insertNames() 18{ 19 for (int i = 0; i < erasNames.size(); i++) 20 { 21 names.push_back(make_tuple(erasNames[i], erasYears[i])); 22 } 23}

cpp

1//convert.cpp 2#include "era.hpp" 3void JCtoAC(string eraName, int eraNum) 4{ 5 insertNames(); 6 int sumNum = 0; 7 for (int i = 0; i < names.size(); i++) 8 { 9 string key = get<0>(names[i]); 10 int value = get<1>(names[i]); 11 if (eraName == key) 12 { 13 if (eraNum > value || eraNum <= 0) 14 { 15 cout << "The year " << eraName << eraNum << " doesn't exist." << endl; 16 } 17 else 18 { 19 cout << startYear + sumNum + eraNum << endl; 20 break; 21 } 22 } 23 sumNum += value - 1; 24 } 25} 26 27void ACtoJC(int inputNum) 28{ 29 if (inputNum > thisYear) 30 { 31 cout << "The year " << inputNum << " is the future. It may not be Reiwa Era." << endl; 32 } 33 else if (inputNum < startYear) 34 { 35 cout << "Sorry, I don't know about before" << startYear << endl; 36 } 37 else 38 { 39 int subNum = 0; 40 insertNames(); 41 for (int i = 0; i < names.size(); i++) 42 { 43 string key = get<0>(names[i]); 44 int value = get<1>(names[i]); 45 int checkNum = inputNum - startYear - value - subNum; 46 if (checkNum <= 0) 47 { 48 cout << key << value + checkNum << endl; 49 } 50 else 51 { 52 subNum += value - 1; 53 } 54 } 55 } 56}

これらのファイルを作成し、

$ g++ -std=c++11 -o a.out era.cpp

を実行すると

Undefined symbols for architecture x86_64: "JCtoAC(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int)", referenced from: _main in era-ac976a.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

とエラーが出ます。

とりあえずググってincludeやタイポを確認したのですが解決策が見つかりません。コマンドが間違っているのでしょうか。
間違いが分かる方は教えてください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

gccを実行するさい、era.cppだけでなく、names.cppやconvert.cppもコマンドラインに空白区切りで指定してください。

投稿2020/06/07 03:02

編集2020/06/07 03:35
Daregada

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kota.Y

2020/06/07 03:08

実行してみたのですが、 ``` duplicate symbol '_names' in: /var/folders/25/p6fxx4tj6sz7wxrwqsf9j9jm0000gn/T/era-1906ee.o /var/folders/25/p6fxx4tj6sz7wxrwqsf9j9jm0000gn/T/names-3276f6.o duplicate symbol '_names' in: /var/folders/25/p6fxx4tj6sz7wxrwqsf9j9jm0000gn/T/era-1906ee.o /var/folders/25/p6fxx4tj6sz7wxrwqsf9j9jm0000gn/T/convert-68d876.o ld: 2 duplicate symbols for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) ``` というエラーが出力されてしまいました。era.cppはそもそもJCtoACを実行しているだけなので定義がかぶることはないはずなのですが。。。
Daregada

2020/06/07 03:29

質問変わってますが、ヘッダーファイルの中でnamesを定義してるのがまずいです。
Kota.Y

2020/06/07 03:39

ありがとうございます。namesの定義をnames.cppに移したら正常に動作しました。
guest

0

ベストアンサー

3つの .cppファイルを同時に指定してリンクさせるか、あるいは、
-c オプションを指定して個別にコンパイルだけを行い、
3つの .oファイルを同時に指定してリンクさせましょう。

追記
vector<tuple<string, int>> names; は names.cpp(または convert.cpp) の中に書いて、
era.hpp には extern vector<tuple<string, int>> names; と書きましょう。

投稿2020/06/07 03:02

編集2020/06/07 03:26
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問