2013-09-05 38 views
3

我试图通过在独立的头文件/源文件中对函数进行分组来组织我的代码。 #include我的主要.cpp头文件,但编译器没有看到convertTypes.cpp中的函数。是什么赋予了?我该如何在全局范围内使用我的'key'typedef(所以在分离的函数源中也是如此)?很多代码,对不起。如何将全局函数包含在单独的文件中

/* 
* NoteMaker.cpp 
* 
* Created on: Sep 4, 2013 
*  Author: edwinrietmeijer 
*/ 


typedef struct { 
    int keyNum; 
    int keyType; 
} key; 

#include <iostream> 
#include <string> 
#include <iomanip> 
#include "convertTypes.h" 

using namespace std; 

const int KEYSET[ ] = { 0, 2, 4, 5, 7, 8, 9 }; 

int* generateNotes(int, key); 
void echoNoteList(const int* , const int, const key); 
string getKeyStringFromUser(); 

int main() { 

    key keyStruct; 
    int octave; 
    int nrOfNotes; 
    string firstNoteName; 

    // Get inputs 
    cout << "What key would you like to generate notes in? (f, cis, es, etc.)" << endl; 
    firstNoteName = getKeyStringFromUser(); 
    cout << "In what octave would you like to generate notes? (-1/9)" << endl; 
    cin >> octave; 
    octave += 1; 
    cout << "How many notes do you wish to generate?" << endl; 
    cin >> nrOfNotes; 

    // create a key data struct from input string 
    keyStruct = convertKeyStringToKeyStruct(firstNoteName); 

    // add the starting octave nr to the keyStruct 
    keyStruct.keyNum += octave * 12; 

    // generate note list 
    int* noteList = new int[ nrOfNotes ]; 
    noteList = generateNotes(nrOfNotes, keyStruct); 

    // echo note list to terminal 
    echoNoteList(noteList , nrOfNotes, keyStruct); 
    cin.get(); 
} 

int* generateNotes(int notes, key keyStruct) { 
    int* newList = new int [notes]; 
    int currNote = keyStruct.keyNum + keyStruct.keyType; 
    int currDist = 0; 
    newList[0] = currNote; 

    for (int i=1; i < notes; i ++) { 
     currDist = i % 7; 
     if (currDist == 0 || currDist == 3) // half step or whole step? 
     { currNote = currNote + 1; } 
     else 
     { currNote = currNote + 2; } 

     newList[ i ] = currNote; 
    } 
    cout << "Generated list." << endl; 
    return newList; 
} 

void echoNoteList(const int* noteList, const int nrOfNotes, const key thisKeyStruct) 
{ 
    int currNote; 

    for (int i = 0; i < nrOfNotes ; i ++) { 
     currNote = noteList[ i ] % 12; 
     if (currNote < 0) 
      currNote += 12; 
     cout << left; 
     cout << setw(5) << noteList[ i ] << setw(5) << convertToNoteName(currNote, thisKeyStruct.keyType) << endl; 
    } 
} 


string getKeyStringFromUser() { 
    bool correctInput = false; 
    string getKeyName; 
    int keyNum; 
    while (! correctInput) { 
     cin >> getKeyName; 
     cout << endl; 
     keyNum = getKeyName[ 0 ]; 
     if (keyNum > 96 && keyNum < 104) { 
      correctInput = true; 
     } 
     else 
     { 
      cout << "Wrong input. Try again." << endl; 
     } 
    } 
    return getKeyName; 
} 

convertTypes.h

#ifdef CONVERTTYPES_H 
#define CONVERTTYPES_H 

std::string convertToNoteName(int, int); 

key convertKeyStringToKeyStruct(std::string); 

#endif 

convertTypes.cpp

/* 
* convertTypes.cpp 
* 
* Created on: Sep 5, 2013 
*  Author: edwinrietmeijer 
*/ 
#include <string> 
#include "convertTypes.h" 

using namespace std; 

typedef struct { 
    int keyNum; 
    int keyType; 
} key; 

key convertKeyStringToKeyStruct(string firstNote) { 
    int stringSize; 
    int keyType = 0; 
    char keyChar; 
    key thisKey; 
    keyChar = firstNote[ 0 ]; 

    // get key type (flat, sharp, normal) 
    stringSize = firstNote.size(); 
    if (stringSize > 1) { 
     switch(firstNote[ 1 ]) { 
     case 'e': 
      keyType = -1; break; 
     case 's': 
      keyType = -1; break; 
     case 'i': 
      keyType = 1; break; 
     default: 
      keyType = 0; break; 
     } 
    } 
    // convert key char to ascii code 
    int ASkey = keyChar; 
    thisKey.keyNum = KEYSET[ ASkey - 99 ]; 
    thisKey.keyType = keyType; 
    return thisKey; 
} 


string convertToNoteName(int thisNote, int thisKeyType = 0) { 

    string noteName; 
    char addKeyType; 

    switch(thisKeyType) { 
    case -1: 
     addKeyType = 'b'; break; 
    case 0: 
     addKeyType =' '; break; 
    case 1: 
     addKeyType = '#'; break; 
    } 

     switch(thisNote) { 
     case 0: 
      noteName = "C"; break; 
     case 1: 
      if(thisKeyType == 1) 
       noteName = string ("C") + addKeyType; 
      else 
       noteName = string("D") + addKeyType; break; 
     case 2: 
      noteName = "D"; break; 
     case 3: 
      if(thisKeyType == 1) 
       noteName = string ("D") + addKeyType; 
      else 
       noteName = string("E") + addKeyType; break; 
     case 4: 
      noteName = "E"; break; 
     case 5: 
      noteName = "F"; break; 
     case 6: 
      if(thisKeyType == 1) 
       noteName = string ("F") + addKeyType; 
      else 
       noteName = string("G") + addKeyType; break; 
     case 7: 
      noteName = "G"; break; 
     case 8: 
      if(thisKeyType == 1) 
       noteName = string ("G") + addKeyType; 
      else 
       noteName = string("A") + addKeyType; break; 
     case 9: 
      noteName = "A"; break; 
     case 10: 
      if(thisKeyType == 1) 
       noteName = string ("A") + addKeyType; 
      else 
       noteName = string("B") + addKeyType; break; 
     case 11: 
      noteName = "B"; break; 
     default: 
      noteName = "!"; break; 
     } 
     return noteName; 
} 
+1

您需要定义所有类型你使用它们,所以你需要在convertTypes.h中声明'key'结构体,如果你想让你的函数返回它的话。 – PeterT

+1

不要为很多代码道歉 - 使它不会有很多代码。分而治之是一项至关重要的调试技巧,您现在可以了解它。 –

+0

除了'#ifdef'之外,你应该在'convertTypes.h'中#include ''。 – juanchopanza

回答

4

变化:

#ifdef CONVERTTYPES_H 

到:

#ifndef CONVERTTYPES_H 

您正在有效地编译出您的定义。

关于你的第二点,移动这样的:

typedef struct { 
    int keyNum; 
    int keyType; 
} key; 

到头文件(在第一次使用前,在那里)。

但是,我会警告不要使用名称,如key,因为它通常用作变量名称。我会去key_tMySpecialKeyForStuffImDoing(或某些)。

+0

啊,谢谢。 Noob错误:) – staxas

+0

顺便说一句,是否有一个常见的做法来定义大型项目的单独文件中的全局类型,枚举等?假设我想在多个.h/.cpp文件中使用'key'结构,我想为此创建一个独立的结构吗? – staxas

+0

@staxas是的,这很常见。创建一个名为'Types.h'或'MyTypes.h'的文件,并将它们包含在任何使用它们的**头文件**中。 – trojanfoe

3

除了@ trojanfor的前面回答:还创建包含key结构定义一个新的NoteMaker.h或stuct定义移动到convertTypes.h,这样你就不会复制它在多个地方

+0

我已经将typedef移至NoteMaker.h,但convertTypes不再识别'key'。在我的convertTypes.h中需要#include“NoteMaker.h”吗? – staxas

+0

是的,绝对是! –

相关问题