I am trying to pass some strings trough espeak and it reads them but I get “segmentation fault”

北城余情 提交于 2019-12-24 21:35:23

问题


This is my code. I want to get 5 strings from the user and espeak reads each of them when user interred it. But I get segmentation fault(core dumped) message.

#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;
}

I tried some modification but none of them worked. I want the program works like this:

User input: hi

espeak says: hi

user input: one

espeak says: one

(for 5 inputs)

But when I try to interring more than 4 characters as input,it gives segmentation fault error!


回答1:


The two main issues are:

  1. you use strlen on an uninitialized array of chars;
  2. the unique_identifier argument of espeak_Synth must be NULL or point to an unsigned int (see the source code) while now it is an unsigned pointer to random memory.

Move strlen after scanf, use NULL instead of unique_identifier and your code will suddenly work (kind of).

There are many other issues though: useless variables, uninitialized variables, no input sanitization and more. IMO a better approach would be to throw away the test function and rewrite it from scratch properly.

Addendum

This is how I'd rewrite the above code. It is still suboptimal (no input sanitization, no error checking) but IMO it is much cleaner.

#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;
}


来源:https://stackoverflow.com/questions/47772076/i-am-trying-to-pass-some-strings-trough-espeak-and-it-reads-them-but-i-get-segm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!