2

文字列の文字からビープ音を作成しようとしています。コードは次のとおりです。

/*
 * Buzzer connected to Arduino uno digital pin 13
 * Switch connected to digital pin 2
 */ 

#include <avr/io.h>
#include <util/delay.h>

const int TBEEP = 1000;
const int TBEEEEP = 3500;
const int TGAP = 500;
const int TGAPLETTER = 2000;
int portb = 0x20;

void beep() {
    PORTB = ~portb; _delay_ms(TGAP);
    PORTB = portb; _delay_ms(TBEEP);
    PORTB = ~portb; _delay_ms(TGAP);
}

void beeeep() {
    PORTB = ~portb; _delay_ms(TGAP);
    PORTB = portb; _delay_ms(TBEEEEP);
    PORTB = ~portb; _delay_ms(TGAP);
}

void gapLetter() {
    PORTB = ~portb; _delay_ms(TGAPLETTER);
}

void morse_S() {
    beep(); beep(); beep();
    gapLetter();
}

void morse_M() {
    beeeep(); beeeep();
    gapLetter();
}

void morse_SMS() {
    morse_S(); morse_M(); morse_S();
}

void morse(char theString[]) {
    for (int i = 0; theString[i] != '\0'; i++)
    {
        if(&theString[i] == "S")
            morse_S();
        else if(&theString[i] == "M")
            morse_M();
    }
}

int main (void)
{
    DDRB = 0xFF;
    DDRD = 0x00;
    PORTD = 0x04;

    while (1) {
        if (PIND & 0x04) {
            PORTB = ~0x20;
        } else {
            //morse_SMS(); // it works
            morse("SMS"); // this one doesnt work like morse_SMS() PLEASE HELP!
        }
    }
    return 0;
}

functionvoid morse(char theString[]) {...}では、文字列「SMS」のすべての文字からビープ音を出したいです。残念ながら最後のキャラしか作れません。

私は Atmel Studio 6 を使用しています。ソリューション (F7) をビルドすると、エラーは表示されませんが、理解できない警告が表示されます (まったく初心者で申し訳ありません)。

文字列リテラルとの比較で未指定の動作が発生する [-Waddress]

すべてのキャラクターに次々とビープ音を鳴らすにはどうすればよいですか?

4

2 に答える 2

4

初めに、

const int TBEEP = 1000;
const int TBEEEEP = 3500;

これらは私の一日を作りました。:)


それとは別に、初心者向けの優れた C の本を入手する必要があります。==内容ではなくポインターを比較するため、演算子を使用して文字列を比較することはできません。文字列を比較する場合はstrcmp()、C 標準ライブラリの関数を使用します。

しかし、あなたの場合、文字列を比較したくありません。文字を比較したい。==文字ポインタを逆参照して実際の文字を取得し、それを文字列リテラルではなく文字リテラルと比較するだけです。

if (theString[i] == 'S')
    morse_S();
else if (theString[i] == 'M')
    morse_M();

ああ、おそらくあなたはその巨大な連鎖if...else if...elseモンスターを避けたいと思うでしょう. UTF-8 または少なくとも ASCII エンコーディングを想定すると、英字の文字コードはアルファベット順に次のようになります。

void (*morse_funcs[26])();
morse_funcs[0] = morse_A;
morse_funcs[1] = morse_B;
// ...
morse_funcs[25] = morse_Z;

// ...

void morse(const char *s)
{
    while (*s)
        morse_funcs[tolower(*s++) - 'a']();
}

char *また、私がどのように に変わったかにも注目してconst char *ください。文字列を変更しない場合は、変更するつもりがないことをコンパイラに伝えてください。そうすれば、文字列リテラルも安全に渡すことができます。

さらに良いことに、関数ポインターのテーブルではなく、モールス符号のテーブルを使用します。このような:

const char *mcodes[26] = {
    ".-",        // 'a'
    "-...",      // 'b'
    // etc...
    "--.."       // 'z'
};

void do_morse(const char *code)
{
    while (*code)
        if (*code++ == '-')
            beeeep();
        else
            beep();
}

void morse(const char *s)
{
    while (*s)
        do_morse(mcodes[tolower(*s++) - 'a']);
}
于 2013-07-28T07:47:58.467 に答える
0

これを試して:

void morse(char theString[]) {
    for (int i = 0; theString[i] != '\0'; i++)
    {
        if(theString[i] == 'S')
            morse_S();
        else if(theString[i] == 'M')
            morse_M();
    }
}
于 2013-07-28T07:54:06.890 に答える