2016-04-19 2 views
0

Я создал программу, которая воспроизводит музыку в моем музыкальном каталоге и поддерживает пробелы, благодаря помощи Google. Тем не менее, я не хочу сохранять жесткое кодирование имен песен, поэтому мне интересно, могу ли я заменить имя файла переменной и std :: cin переменную, когда моя программа запущена. Однако, Я также хочу, чтобы играть песни, в которых есть свои имена. Я сделал функцию обертки (я думаю, что это будет считаться одним?) Для mciSendString, и я пытаюсь передать ему параметр «name» для его воспроизведения. Однако из-за осложнений с LPCWSTR и std :: string, среди прочего, мне трудно выполнить это.Как заставить mciSendString работать с переменными и пробелами?

Вот моя текущая музыка функция:

void Music(std::string strSongName,DWORD dwExtraFlag) 
{ 

    MCIERROR me = 
     mciSendString(TEXT("open \"D:\\Windows.old\\Users\\MyName\\Desktop\\Sounds\\Music\\song name.mp3\""" type mpegvideo alias song1"), 
      NULL, 0, 0); 

/* 
note that I want to be able to play songs 
with spaces in their name 
*/ 

    if (me == 0) 
    { 
     me = mciSendString(TEXT("play song1 wait repeat"), NULL, 0, 0); 
     mciSendString(TEXT("close song1"), NULL, 0, 0); 
    } 
} 

То, что я хочу, чтобы это было как:

void Music(std::string strName,DWORD dwExtraFlag) 
{ 

    MCIERROR me = 
     mciSendString(TEXT("open \"D:\\Windows.old\\Users\\MyName\\Desktop\\Sounds\\Music\\STRNAMEVARIABLEHERE.mp3\""" type mpegvideo alias song1"), 
      NULL, 0, 0); 

/* 
note that I want to be able to play songs 
with spaces in their name 
*/ 

    if (me == 0) 
    { 
     me = mciSendString(TEXT("play song1 wait repeat"), NULL, 0, 0); 
     mciSendString(TEXT("close song1"), NULL, 0, 0); 
    } 
} 

Я бы тогда сделать переменную в основной или какой-либо другой функции и зЬй :: CIN в эта переменная.

std::string strNameOfSong = ""; 
std::cin >> strNameOfSong; 

Тогда я назвал бы музыку, как:

Music(strNameOfSong,0) 

Я хотел бы также отметить, что вы можете игнорировать «dwExtraFlags» аргумент, если вы хотите, это то, что я до сих пор реализовать ,

В любом случае, я был бы очень признателен за помощь в реализации этого, поскольку я новичок в C++. Однако я не хочу оставлять этот проект незавершенным, и я хочу завершить его, прежде чем двигаться дальше.

Я бы очень признателен за любые решения, помощь или советы. Если вы хотите, чтобы я был более конкретным или предоставил больше информации, чтобы помочь вам сформулировать ответ, я был бы рад сделать это.

спасибо.

EDIT: Я внедрил предложение Итана. Добавив некоторые вещи и добавив свое предложение, моя программа перестает работать вскоре после ввода имени песни, которую я хочу. Я попробовал отладку, и он сообщает:

«Исключение выбрано в 0x00047430 в Program.exe: 0xC0000005: место записи нарушения доступа 0x6563696E».

Вот что я добавил в свою основную функцию (в сторону от предложения Этана):

static std::string strSongName = ""; 
    std::cin >> strSongName; 
    CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&Music, &strSongName, 0, 0); 
    // The above is to createthread so I can play music while doing other things 

Debugging, значения кажутся правильными. Однако я вдруг получаю это исключение, и приложение перестает работать. Как я могу получить нарушение доступа?

Еще одно небольшое изменение, которое я сделал предложение Итана:

MCIERROR me = 
     mciSendString((LPCWSTR)(songFile.c_str()), NULL, 0, 0); 

(я typecasted SongFile как это дает мне ошибки)

Я также изменил пример пути назад к нормальному.

EDIT2:

Исправлено исключение! Это потому, что я (глупым образом) забыл разыменовать указатель на «strSongName». Однако, что-то после того, как пространство все еще не распознается, кажется, поскольку я отлаживал его. Он также, похоже, не воспроизводит песни, даже когда у них нет места, и да, я тоже добавляю .mp3.

+0

Вы хотите сказать, что вы пытаетесь заменить имя песни на входную строку, которая может содержать пробелы? –

+0

искать ['std :: getline'] (http://en.cppreference.com/w/cpp/string/basic_string/getline). В этом случае 'std :: getline (cin, strNameOfSong);' Это будет захватывать все на консоли до конца строки, поэтому, если вы введете * (Все, что я делаю), я сделаю это для вас * и нажмите enter, 'strNameOfSong' будет равен" (Все, что я делаю) Я делаю это для вас ". – user4581301

+0

Да, я, Этан. –

ответ

0

Как насчет этого?

void Music(std::string strName,DWORD dwExtraFlag) 
{ 
std::string songFile = "open \"D:\\Windows.old\\Users\\MyName\\Desktop\\Sounds\\Music\\"; 
songFile += strName + "\" type mpegvideo alias song1"; 

MCIERROR me = 
    mciSendString(songFile.c_str(), NULL, 0, 0); 

/* 
note that I want to be able to play songs 
with spaces in their name 
*/ 

if (me == 0) 
{ 
    me = mciSendString(TEXT("play song1 wait repeat"), NULL, 0, 0); 
    mciSendString(TEXT("close song1"), NULL, 0, 0); 
} 
} 
+0

Обратите внимание, что 'mciSendString (songFile.c_str(), ...)' будет компилироваться только в том случае, если 'UNICODE' не определен, так как' mciSendString() 'ожидает вход' TCHAR * '. 'std :: string' использует' char' вместо 'TCHAR', поэтому было бы безопаснее использовать' mciSendStringA() 'с' std :: string' или 'mciSendStringW()' с 'std :: wstring'. –

+0

Да @ RemyLebeau Вы правы в отношении вещи UNICODE. Чтобы избежать ошибки, используйте переключатель определения (#ifdef UNICODE), чтобы выбрать другой код. –