エラー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら

エラー

#1

投稿記事 by » 16年前

char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );

delete [/url] p;

CString newText;
char *p2="";

int i=0;
while(1){
if(p=='。')
break;
else if(p=='\0')
break;
p2 = p[i++];
}
文章「。」で止まってくれません!!!!!!!!!

Dixq (管理人)

Re:エラー

#2

投稿記事 by Dixq (管理人) » 16年前

「。」というのは2バイト文字ではないでしょうか?
全角文字だと配列要素一つでは表せず、2つで1つの文字を表しますが、
上のプログラムだと配列要素一つとしか比較をしていないので出来ないのだと思います。

また、タイトルには解り易い記述を、そしてお名前はなるべくユニークなものにして頂けると助かります。

あいーん

Re:エラー

#3

投稿記事 by あいーん » 16年前

すいません初心者で、、、char型は4バイトではないのでしょうか?

box

Re:エラー

#4

投稿記事 by box » 16年前

> char型は4バイトではないのでしょうか?

違います。
sizeof(char)は1です。

ところで、ソースコードを貼り付ける際、
全体がそれほど長くないのであれば
すべて貼り付けませんか?
というのは、一部分だけ貼り付けてあっても、
回答しようとする側でコンパイルできないためです。

あいーん

音声合成の改良

#5

投稿記事 by あいーん » 16年前

すいません。
このプログラムは、音声合成ができるものです。そこで元のプログラムを改良して、文字を読み上げる際に「。」という文字が来たら次の文字を読む前に一時停止するというものを作りたいのですが、なかなかエラーで作れません。どうしたらよいのでしょうか?


プログラム


#include "stdafx.h"
#include "SampleSpeech.h"
#include "SampleSpeechDlg.h"
#include <sapi.h>
#include<stdio.h>
#include <time.h>


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[/url] = __FILE__;
#endif



/////////////////////////////////////////////////////////////////////////////
// アプリケーションのバージョン情報で使われている CAboutDlg ダイアログ

class CAboutDlg : public CDialog
{
public:
CAboutDlg();

// ダイアログ データ
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA

// ClassWizard は仮想関数のオーバーライドを生成します
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV のサポート
//}}AFX_VIRTUAL

// インプリメンテーション
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// メッセージ ハンドラがありません。
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSampleSpeechDlg ダイアログ

CSampleSpeechDlg::CSampleSpeechDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSampleSpeechDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CSampleSpeechDlg)
m_sText = _T("");
//}}AFX_DATA_INIT
// メモ: LoadIcon は Win32 の DestroyIcon のサブシーケンスを要求しません。
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSampleSpeechDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSampleSpeechDlg)
DDX_Text(pDX, IDC_EDIT1, m_sText);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CSampleSpeechDlg, CDialog)
//{{AFX_MSG_MAP(CSampleSpeechDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSampleSpeechDlg メッセージ ハンドラ

BOOL CSampleSpeechDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// "バージョン情報..." メニュー項目をシステム メニューへ追加します。

// IDM_ABOUTBOX はコマンド メニューの範囲でなければなりません。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}

// このダイアログ用のアイコンを設定します。フレームワークはアプリケーションのメイン
// ウィンドウがダイアログでない時は自動的に設定しません。
SetIcon(m_hIcon, TRUE); // 大きいアイコンを設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンを設定

// TODO: 特別な初期化を行う時はこの場所に追加してください。

return TRUE; // TRUE を返すとコントロールに設定したフォーカスは失われません。
}

void CSampleSpeechDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}


void CSampleSpeechDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
HCURSOR CSampleSpeechDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CSampleSpeechDlg::OnButton1()
{

UpdateData();
ISpVoice* pVoice = NULL;

if (FAILED(CoInitialize(NULL)))
{
AfxMessageBox("Error to intiliaze COM");
return;
}

HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice);

if( SUCCEEDED( hr ) )
{

/*ここが変更した場所*/
char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );

delete [/url] p;

CString newText;
char *p2 = new char[m_sText.GetLength()+1];
strcpy( p2, "" );
delete [/url] p2;

int i = 0;
while(1){
if(*p=='。')
break;
else if(*p=='\0')
break;
*p2++ = *p++;
}

newText = p2;



hr = pVoice->Speak(newText.AllocSysString(), SPF_DEFAULT, NULL);
pVoice->Release();
pVoice = NULL;
}


CoUninitialize();

}

void CSampleSpeechDlg::OnButton2()
{ AfxGetMainWnd()->PostMessage(WM_CLOSE);


}

Mist

Re:音声合成の改良

#6

投稿記事 by Mist » 16年前

ソースを掲示する場合は規約に従いpreタグを使用してください。

変更した場所についてざっと見ましたがC++をよく理解されいないご様子。
元がどうだったのかわかりませんがnewして確保し領域を即座にdeleteで解放していたり
していて、「。」の判定以外にもおかしなところだらけです。

質問者さんはC++についてどの程度習得されていますか?

あいーん

Re:音声合成の改良

#7

投稿記事 by あいーん » 16年前

全くの初心者です。。
char *p = new char[m_sText.GetLength()+1];
strcpy( p, m_sText );

delete [/url] p;

の部分はCCString型からchar型へ変更するためのプログラムを参考にしました。

Mist

Re:音声合成の改良

#8

投稿記事 by Mist » 16年前

参考にしたのはここですかね?
http://rararahp.cool.ne.jp/vc/vctips/cstringchar.htm

参考にするのはいいんですけど理解していないと意味がないですね。
いろいろな例を理解せず流用してくっつけただけでは正しいプログラムはできません。

例えば

delete [/url] p;

とした段階でnewで確保したメモリは解放されているためアクセスしてはいけません。
pに確保した領域を使用するのはdeleteよりも前です。
まず、これだけでも修正できますか?

バグ

Re:エラー

#9

投稿記事 by バグ » 16年前

CStringの中身をconst char*として扱いたいなら、GetBuffer関数が手軽ですよ。

閉鎖

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