文字をモールス信号のwavにするプログラムでうまく出力できない

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fabersid
記事: 42
登録日時: 1年前

文字をモールス信号のwavにするプログラムでうまく出力できない

#1

投稿記事 by fabersid » 3週間前

文字列の長さに応じて可変の長さになるようにしようとしたのですが、
2週回して処理する方法にするとどこかが壊れてしまいました。
どこを直せばいいでしょうか?
マジックナンバーが多いです、私は理解できていません

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
//int ones=20000,hfs=10000,qts=4000;
int ones=10,hfs=5,qts=2;
struct header{
    char riffChunkId[4];
    int riffChunkSize;
    char waveHeader[4];
    char fmtChunkId[4];
    int fmtChunkSize;
    short int formatId;
    short int channel;
    unsigned int samplingRate;
    unsigned int transferRate;
    unsigned short int blockSize;
    unsigned short int quantizationBits;
    char dataChunkId[4];
    unsigned int dataChunkSize;
}header;
int setHeader(void){
    strcpy(header.riffChunkId,"RIFF");
    header.riffChunkSize=0;//705636;
    strcpy(header.waveHeader,"WAVE");
    strcpy(header.fmtChunkId,"fmt ");
    header.fmtChunkSize=16;
    header.formatId=1;
    header.channel=1;
    header.samplingRate=44100;
    header.transferRate=88200;
    header.blockSize=2;
    header.quantizationBits=16;
    strcpy(header.dataChunkId,"data");
    header.dataChunkSize=0;//44100*2*8;
    return header.dataChunkSize/header.blockSize;
}
short int *data;
int writeFile(char *fileName){
    FILE *f2;
    int a,ret;
    f2=fopen(fileName,"wb");
    fwrite(&header,44,1,f2);
    printf("\n%d %d\n",header.dataChunkSize,header.blockSize);
    a=header.dataChunkSize/header.blockSize;
    ret=fwrite(data,2,a,f2);
    fclose(f2);
    return ret;
}
void beep_format(char beeps[],int *di,int *x){
    float onkai[]={0,800};
    int j,limit,i;
    size_t si;
    for(si=0;si<strlen(beeps);si++){
        switch(beeps[si]){
            case '2':limit=ones;j=1;break;
            case '1':limit=hfs;j=1;break;
            case '0':limit=qts;j=0;break;
        }
        for(i=0;i<limit;i++){
            if(*x==1)data[(*di)]=30000*sin(3.1416*2*onkai[j]/44100*(*di));
            if(*x==1&&ones+hfs+qts<20)printf("%d\t%d\t%d\n",(*di),j,data[(*di)]);
            (*di)++;
        }
    }
}

int main(int argc,char *argv[]){
    int i=0,x,a;
    char moji[30];
    char str;
    setHeader();
    if(argc>=2){
        printf("半角カタカナの文字列を入力してください\n半角カタカナはひらがなを入力した後にF8キーを押すことで入力できます。\n");
        scanf("%s",moji);
        setHeader();
        for(x=0;x<2;x++){
            a=0;
            i=0;
            while(moji[a]!='\0'){
                str=moji[a];
                switch(str){
                    case 'ア':beep_format("2020102020",&i,&x);break;
                    case 'イ':beep_format("1020",&i,&x);break;
                    case 'ウ':beep_format("101020",&i,&x);break;
                    case 'エ':beep_format("2010202020",&i,&x);break;
                    case 'オ':beep_format("1020101010",&i,&x);break;
                    case 'カ':beep_format("10201010",&i,&x);break;
                    case 'キ':beep_format("2010201010",&i,&x);break;
                    case 'ク':beep_format("10101020",&i,&x);break;
                    case 'ケ':beep_format("20102020",&i,&x);break;
                    case 'コ':beep_format("20202020",&i,&x);break;
                    case 'サ':beep_format("2010201020",&i,&x);break;
                    case 'シ':beep_format("2020102010",&i,&x);break;
                    case 'ス':beep_format("2020201020",&i,&x);break;
                    case 'セ':beep_format("1020202010",&i,&x);break;
                    case 'ソ':beep_format("20202010",&i,&x);break;
                    case 'タ':beep_format("2010",&i,&x);break;
                    case 'チ':beep_format("10102010",&i,&x);break;
                    case 'ツ':beep_format("10202010",&i,&x);break;
                    case 'テ':beep_format("1020102020",&i,&x);break;
                    case 'ト':beep_format("1010201010",&i,&x);break;
                    case 'ナ':beep_format("102010",&i,&x);break;
                    case 'ニ':beep_format("20102010",&i,&x);break;
                    case 'ヌ':beep_format("10101010",&i,&x);break;
                    case 'ネ':beep_format("20201020",&i,&x);break;
                    case 'ノ':beep_format("10102020",&i,&x);break;
                    case 'ハ':beep_format("20101010",&i,&x);break;
                    case 'ヒ':beep_format("2020101020",&i,&x);break;
                    case 'フ':beep_format("20201010",&i,&x);break;
                    case 'ヘ':beep_format("10",&i,&x);break;
                    case 'ホ':beep_format("201010",&i,&x);break;
                    case 'マ':beep_format("20101020",&i,&x);break;
                    case 'ミ':beep_format("1010201020",&i,&x);break;
                    case 'ム':beep_format("20",&i,&x);break;
                    case 'メ':beep_format("2010101020",&i,&x);break;
                    case 'モ':beep_format("2010102010",&i,&x);break;
                    case 'ヤ':beep_format("102020",&i,&x);break;
                    case 'ユ':beep_format("2010102020",&i,&x);break;
                    case 'ヨ':beep_format("2020",&i,&x);break;
                    case 'ラ':beep_format("101010",&i,&x);break;
                    case 'リ':beep_format("202010",&i,&x);break;
                    case 'ル':beep_format("2010202010",&i,&x);break;
                    case 'レ':beep_format("202020",&i,&x);break;
                    case 'ロ':beep_format("10201020",&i,&x);break;
                    case 'ワ':beep_format("201020",&i,&x);break;
                    case 'ヲ':beep_format("10202020",&i,&x);break;
                    case 'ン':beep_format("1020102010",&i,&x);break;
                    case 'ー':beep_format("1020201020",&i,&x);break;
                    case '゙':beep_format("1010",&i,&x);break;
                    case '゚':beep_format("1010202010",&i,&x);break;
                    case '、':beep_format("102010201020",&i,&x);break;
                }
                a++;
            }
            data=(short int *)malloc(i * sizeof(short int));
        }
        header.dataChunkSize=i*2;
        header.riffChunkSize=i*2+36;
        printf("write data=%d \n",writeFile(argv[1]));
    }else{
        printf("引数が足りません\n");
    }
    return 0;
}

アバター
みけCAT
記事: 6216
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: 文字をモールス信号のwavにするプログラムでうまく出力できない

#2

投稿記事 by みけCAT » 2週間前

とりあえずすぐに気付くこととしては、
4バイトしかない領域にstrcpyで終端のナル文字を含めて5バイトの文字列をぶち込んでいるので、
範囲外へのアクセスが発生し、未定義動作になります。
strcpyではなく、memcpyでサイズを指定してコピーするようにするといいでしょう。

また、せっかく2周目のループでデータを格納しても、
またdataに新しいバッファの領域を入れ、データを格納したバッファを投げ捨ててしまうのもよくないですね。
2周目はdataへの代入をしないようにするべきでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

fabersid
記事: 42
登録日時: 1年前

Re: 文字をモールス信号のwavにするプログラムでうまく出力できない

#3

投稿記事 by fabersid » 2週間前

みけCAT さんが書きました:
2週間前
strcpyではなく、memcpyでサイズを指定してコピーするようにするといいでしょう。
strcpyからmemcpyに変えました
みけCAT さんが書きました:
2週間前
また、せっかく2周目のループでデータを格納しても、
またdataに新しいバッファの領域を入れ、データを格納したバッファを投げ捨ててしまうのもよくないですね。
2周目はdataへの代入をしないようにするべきでしょう。
この部分はすみませんわかりませんでした。

fabersid
記事: 42
登録日時: 1年前

Re: 文字をモールス信号のwavにするプログラムでうまく出力できない

#4

投稿記事 by fabersid » 2週間前

あ、すみません、わかりました
mainのほうを見逃してました

返信

“C言語何でも質問掲示板” へ戻る