Skip to main content
Visitor II
August 28, 2024
Solved

scanf() can only read one character

  • August 28, 2024
  • 4 replies
  • 1924 views

I am trying to use scanf() in STM32H743, referring a webpage (here). More specifically, after setting up USART1 in STM32CubeMX, I add some function prototypes like:

 

 

 

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#define GETCHAR_PROTOTYPE int __io_getchar(void)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#define GETCHAR_PROTOTYPE int fgetc(FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
 HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
 return ch;
}

GETCHAR_PROTOTYPE
{
 uint8_t ch = 0;

 /* Clear the Overrun flag just before receiving the first character */
 __HAL_UART_CLEAR_OREFLAG(&huart1);

 /* Wait for reception of a character on the USART RX line and echo this
 * character on console */
 HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
 // HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
 return ch;
}

 

 

 

and add a scanf() in the main function before infinite while loop:

 

 

 

scanf("%c", &c);

 

 

 

where c is a char.

I found that if I read one character (e.g. a char variable) every time, the function works well. But if I try to read more like integers and strings, the function seems being stuck. I don't know where it is stuck and why it happened. Please help. Any help is appreciated.

 

EDIT: I have added "setvbuf(stdin, NULL, _IONBF, 0);" before any scanf() call.

    This topic has been closed for replies.
    Best answer by LittleYe233

    @Peter BENSCH @SMarie @Andrew Neil Thanks for your fast replies. I forget to mention in the first thread that I actually added "setvbuf()" before any scanf() call. And I found that this situation happened because I forgot to automatically add LF after my input in the serial termial. With LF or CR/LF, scanf() begins to work well again. That's all my fault and thank you all again.

    4 replies

    Technical Moderator
    August 28, 2024

    Try deactivating the buffering before scanf():

    setvbuf(stdin, NULL, _IONBF, 0);

    Regards
    /Peter

    Graduate II
    August 28, 2024

    Did you add the config indicated in the link you gave ?

    setvbuf(stdin, NULL, _IONBF, 0);

    If not could you try it ?
    If you did, could you show us the rest of your code ?

    S. Marie

    Super User
    August 28, 2024

    @LittleYe233 wrote:

    But if I try to read more like integers and strings, the function seems being stuck.


    How, exactly, are you testing that?

    @Peter BENSCH and @SMarie have suggested disabling buffering - so does your input work as-is if you terminate entry with CR and/or LF ?

     

    EDIT:

    See this thread on the buffering of stdin, etc:

    https://community.st.com/t5/stm32-mcus-products/stm32g030-usart-and-hal-delay-strange-behavior/m-p/640684

     

    LittleYe233AuthorAnswer
    Visitor II
    August 28, 2024

    @Peter BENSCH @SMarie @Andrew Neil Thanks for your fast replies. I forget to mention in the first thread that I actually added "setvbuf()" before any scanf() call. And I found that this situation happened because I forgot to automatically add LF after my input in the serial termial. With LF or CR/LF, scanf() begins to work well again. That's all my fault and thank you all again.

    Super User
    August 28, 2024

    Good to hear - please mark the solution:

    https://community.st.com/t5/community-guidelines/help-others-to-solve-their-issues/ta-p/575256

    I think this is defined behaviour for stdin in the standard C library.