Это мой код Я хочу получить 5 строк от пользователя, и espeak читает каждую из них, когда пользователь ее перехватил. Но я получаю segmentation fault(core dumped)
сообщение.
#include <string.h>
#include <malloc.h>
#include <espeak/speak_lib.h>
int test()
{
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 500, Options=0;
void* user_data;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;char Voice[] = {"English"};
int i=0;
char text[1000];
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;output = AUDIO_OUTPUT_PLAYBACK;
espeak_Initialize(output, Buflength, path, Options );
espeak_SetVoiceByName(Voice);
const char *langNativeString = "en_US";
espeak_VOICE voice={0};
voice.languages = langNativeString;
voice.name = "US";
voice.variant = 2;
voice.gender = 1;
Size = strlen(text)+1;for (i=0; i<5; i++)
{
scanf("%s ", &text);
printf("%s", text);
espeak_Synth( text, Size, position, position_type, end_position, flags,
unique_identifier, user_data );
espeak_Synchronize( );
fflush(stdout);
}
return 0;
}
int main(int argc, char* argv[] )
{
test();
return 0;
}
Я попробовал некоторые модификации, но ни один из них не сработал. Я хочу, чтобы программа работала так:
Ввод пользователя: привет
espeak говорит: привет
пользовательский ввод: один
эспик говорит: один
(на 5
входы)
Но когда я пытаюсь ввести более 4 символов в качестве входных данных, это дает segmentation fault
ошибка!
Два основных вопроса:
strlen
на неинициализированном массиве символов;unique_identifier
аргумент espeak_Synth
должно быть NULL
или указать на беззнаковое целое (см. исходный код) пока это беззнаковый указатель на случайную память.Переехать strlen
после scanf
использовать NULL
вместо unique_identifier
и ваш код будет внезапно работать (вроде).
Однако есть много других проблем: бесполезные переменные, неинициализированные переменные, отсутствие очистки входных данных и многое другое. ИМО лучшим подходом было бы выбросить test
функционировать и переписать его с нуля должным образом.
Вот как я бы переписал приведенный выше код. Это все еще неоптимально (без очистки входных данных, без проверки ошибок), но IMO это много очиститель.
#include <stdio.h>
#include <string.h>
#include <espeak/speak_lib.h>
static void say(const char *text)
{
static int initialized = 0;
if (! initialized) {
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 0, NULL, 0);
espeak_SetVoiceByName("en");
initialized = 1;
}
espeak_Synth(text, strlen(text)+1,
0, POS_CHARACTER, 0,
espeakCHARS_UTF8, NULL, NULL);
espeak_Synchronize();
}
int main()
{
char text[1000];
int i;
for (i = 0; i < 5; ++i) {
scanf("%s", text);
say(text);
}
return 0;
}
Других решений пока нет …