3

個別のヘッダー/ソース ファイルに関数をグループ化して、コードを整理しようとしています。メインの .cpp にヘッダー ファイルを #include しましたが、コンパイラは convertTypes.cpp の関数を認識しません。何を与える?また、「キー」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;
}
4

2 に答える 2

4

変化する:

#ifdef CONVERTTYPES_H

に:

#ifndef CONVERTTYPES_H

定義を効果的にコンパイルしています。

あなたの2番目のポイントについては、これを動かしてください:

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

ヘッダーファイルに(そこで最初に使用する前に)。

keyただし、変数名として一般的に使用されるような名前を使用しないように警告します。私はkey_tまたはMySpecialKeyForStuffImDoing(またはそのようなもの)に行きます。

于 2013-09-05T12:03:38.400 に答える
3

@trojanforの回答に加えてNoteMaker.h、構造定義を含む新しいものを作成するkeyか、スタクト定義を移動しconvertTypes.hて、複数の場所で複製しないようにします

于 2013-09-05T12:07:52.467 に答える