readf not assigning properly within looped try-catch - d

If 'a' is typed as input for the program below, instead of an integer, the output goes into a loop without stopping for more input. Why?
uint inputInt = 1;
while (inputInt > 0) {
write("enter something: ");
try {
readf(" %s", inputInt);
writefln("inputInt is: %s", inputInt);
}
catch (Exception ex) {
writeln("does not compute, try again.");
inputInt = 1;
}
}
I would expect inputInt to get assigned '1' in the catch block, and then the try block to be executed again. However, the output shows that the program does not stop to collect inputInt again a second time:
enter something: does not compute, try again.
enter something: does not compute, try again.
enter something: does not compute, try again.
enter something: does not compute, try again.
enter something: does not compute, try again.
etc...

Because when readf fails it doesn't remove the input from the buffer. So the next time round the loop it fails again.
Try this:
import std.stdio;
void main()
{
uint inputInt = 1;
while (inputInt > 0) {
write("enter something: ");
try {
readf(" %s", inputInt);
writefln("inputInt is: %s", inputInt);
}
catch (Exception ex) {
readln(); // Discard current input buffer
writeln("does not compute, try again.");
inputInt = 1;
}
}
}

Related

C++ : why have a return in a if statement?

I've trying to work out why someone would write the following section of code in a Arduino loop. To me, it doesnt make sense, why have a return in a if statement? Does it just return to the start of the loop and not carry on with the rest of the loop. Here's the snippet of interest:
if (!modem.available()) {
Serial.println("No downlink message received at this time.");
return;
}
Here's the full code
/*
Lora Send And Receive
This sketch demonstrates how to send and receive data with the MKR WAN 1300/1310 LoRa module.
This example code is in the public domain.
*/
#include <MKRWAN.h>
LoRaModem modem;
// Uncomment if using the Murata chip as a module
// LoRaModem modem(Serial1);
#include "arduino_secrets.h"
// Please enter your sensitive data in the Secret tab or arduino_secrets.h
String appEui = SECRET_APP_EUI;
String appKey = SECRET_APP_KEY;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
while (!Serial);
// change this to your regional band (eg. US915, AS923, ...)
if (!modem.begin(EU868)) {
Serial.println("Failed to start module");
while (1) {}
};
Serial.print("Your module version is: ");
Serial.println(modem.version());
Serial.print("Your device EUI is: ");
Serial.println(modem.deviceEUI());
int connected = modem.joinOTAA(appEui, appKey);
if (!connected) {
Serial.println("Something went wrong; are you indoor? Move near a window and retry");
while (1) {}
}
// Set poll interval to 60 secs.
modem.minPollInterval(60);
// NOTE: independent of this setting, the modem will
// not allow sending more than one message every 2 minutes,
// this is enforced by firmware and can not be changed.
}
void loop() {
Serial.println();
Serial.println("Enter a message to send to network");
Serial.println("(make sure that end-of-line 'NL' is enabled)");
while (!Serial.available());
String msg = Serial.readStringUntil('\n');
Serial.println();
Serial.print("Sending: " + msg + " - ");
for (unsigned int i = 0; i < msg.length(); i++) {
Serial.print(msg[i] >> 4, HEX);
Serial.print(msg[i] & 0xF, HEX);
Serial.print(" ");
}
Serial.println();
int err;
modem.beginPacket();
modem.print(msg);
err = modem.endPacket(true);
if (err > 0) {
Serial.println("Message sent correctly!");
} else {
Serial.println("Error sending message :(");
Serial.println("(you may send a limited amount of messages per minute, depending on the signal strength");
Serial.println("it may vary from 1 message every couple of seconds to 1 message every minute)");
}
delay(1000);
if (!modem.available()) {
Serial.println("No downlink message received at this time.");
return;
}
char rcv[64];
int i = 0;
while (modem.available()) {
rcv[i++] = (char)modem.read();
}
Serial.print("Received: ");
for (unsigned int j = 0; j < i; j++) {
Serial.print(rcv[j] >> 4, HEX);
Serial.print(rcv[j] & 0xF, HEX);
Serial.print(" ");
}
Serial.println();
}
Being able to return from functions early is one major reason to use functions. Arduino perculiarities aside, a very common case is for example to break out of nested loops. Suppose you have
for (int i = 0; i < imax; ++i) {
for (int j = 0; j < jmax; ++j) {
do_something(i,j);
if (some_condition(i,j)) {
// now I want to break out of both loops...
}
}
}
break only breaks the inner most loop. If you want to break out of more than one nested loop you can introduce bool flags and make them part of the loop conditions, though this ends in a mess rather fast. Usually the much cleaner way is to place the loops in a function and simply return from the function:
void my_nested_loops() {
for (int i = 0; i < imax; ++i) {
for (int j = 0; j < jmax; ++j) {
do_something(i,j);
if (some_condition(i,j)) {
return; // breaks out of both loops
}
}
}
}
In some sense your code is an inside out variant of this. The loop function is called for you in a loop and because the loop is not in your control, you cannot use continue to continue with the next loop iteration, but you can call return.
After return <value>; or just return; (for void functions) the program exits from the loop and also from function. The function returns <value> (for non-void functions). This statement applies when executing function already is not requeris.
simple return; in void function is used to "break" function. When you don't want to execute rest of it program just will return in stack to function what called executing function.

How do i clear the array

I am trying to write a program that can read a string from Serial Monitor Input and count the size of characters as the input data and store the input to the array, but i have some trouble that the Serial monitor will remain the last input data for example if I input ABC it will show "Size of input data = 3 characters" then i input ABC again it will remain the last data that i input before, I already reset it =0 what mistake do i make?
Serial monitor showing:
Please input
Size of input data = 3 characters
ABC
Please input
Please input
Size of input data = 7 characters
ABC
ABC
here's my code:
String Msg ;
char buf[1200]={0} ; // this is an array
char input;
int num=0;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(115200);
while (!Serial)
{
; // wait for serial port to connect. Needed for native USB port only
}
}
void loop() {
while (Serial.available())
{
input = (char)Serial.read();
if(input != '\n' )
{
buf[num] = input;
Msg+=input;
num++;
}
else{
buf[num++] = input; // last character is newline
buf[num] = 0; // string array should be terminated with a zero
Serial.println("Please input");
Serial.print("Size of input data = ");
Serial.print(Msg.length());
Serial.print(" characters");
Serial.println("");
Serial.println(Msg);
Serial.println("Please input");
Serial.println("");
Serial.println("");
for(int i=0; i<num ;i++){
Msg[i]=0;
buf[i] =0;
}
}
num=0;
}
return;
}
According to the Arduino manual the String [] operator does the same as charAt().
As there is also a setCharAt() function I suppose [] and charAt() are read only.
The manual doesn't say that but why would they have a setCharAt() then.
Just assign an empty string to Msg to clear it.
Msg = "";
You are doing it in the wrong way.
Msg is a String type variable, not an array so you can just clear string like below.
Msg="";
Don't use unnecessary for loop to clear a char buf array you can do it in a better way by using the memset function.
memset(buf, 0, sizeof(buf));
and finally, take "num=0;" inside else loop so that it will be zero once completion not every time while loop is executing.
So final tested code will look like this,
String Msg ;
char buf[1200] = {0} ; // this is an array
char input;
int num = 0;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial)
{
; // wait for serial port to connect. Needed for native USB port only
}
}
void loop() {
while (Serial.available())
{
input = (char)Serial.read();
if (input != '\n' )
{
buf[num] = input;
Msg += input;
num++;
}
else {
buf[num++] = input; // last character is newline
buf[num] = 0; // string array should be terminated with a zero
Serial.println("Please input");
Serial.print("Size of input data = ");
Serial.print(Msg.length());
Serial.print(" characters");
Serial.println("");
Serial.println(Msg);
Serial.println("Please input");
Serial.println("");
Serial.println("");
Msg ="";
memset(buf, 0, sizeof(buf));
num = 0;
}
}
return;
}

Unhandled Exception: invalid parameter was passed to a service or function But only after the program has completed

As per an assignment, I've made a child class(PioneerWorld) that inherits publicly from PioneerAm which inherits from PioneerCarRadio, which inherits from the base class CarRadio.
I've then called a function that new the appropriate class object and returns the pointer to a PioneerCarRadio * pRadio pointer.
The program then loops and the user can then choose to change the radio between PioneerCarRadio, PioneerAm, or PioneerWorld. Choosing a different radio deletes the previous object in pRadio and news the appropriate radio with the previously mentioned function.
The problem that occurs is that at any time after I choose to switch to PioneerWorld and then exit the program, the Unhandled exception:
Unhandled exception at 0x7765806C (ntdll.dll) in A-06.exe: 0xC000000D:
An invalid parameter was passed to a service or function. occurred
will occur after the return 0 for the main. Even if the program is exiting when not on the PioneerWorld radio.
It doesn't do this for any of the other radios only when PioneerWorld is chosen at any time during the program will this occur.
From what I can tell the problem resides in the PioneerWorld.h file.
I have tried to add every single kind of exception catch in the try block (granted I don't believe I have a firm knowledge of how the try-catch exception handling works) but none have fixed the problem.
I have run it in debug mode and everything runs smoothly until:
printf("\nGoodbye!\n");
return 0;
} **<-- HERE**
I have tried to place the PioneerWorld higher up on the inheritance hierarchy (eg. rather than
CarRadio-> PioneerCarRadio-> PioneerAm-> PioneerWorld
I changed it to
CarRadio-> PioneerCarRadio-> PioneerWorld-> PioneerAm
And the same problem still occurs.
(Exiting anytime after pRadio has been switched to PioneerWorld radio causes the error but the error does not occur if the radio was never switched to PioneerWorld)
I am honestly at a loss. ;_;
Main:
#include <stdio.h>
#include <string.h>
#include <new.h>
#include <exception>
#include <conio.h>
#include "PioneerWorld.h"
#include <iostream>
#pragma warning(disable :4996)
using namespace std;
//Prototype
PioneerCarRadio * createRadio(char *s);
int main(int argc, char * argv[])
{
//Variables
PioneerCarRadio * pRadio = NULL;
char *arg = argv[argc - 1];
char previousArg[8] = "";
char selection = 0;
//Loops the main process
do
{
//Checks if the previous argument is the same as the current, if not then create a new radio
if (strcmp(previousArg, arg) != 0)
{
//Creates the radio and reads any exceptions thrown
try
{
pRadio = createRadio(arg);
strcpy(previousArg, arg);
}
catch (char* e) //If argument is not present or invalid, exception is caught here
{
printf("\n EXCEPTION: Invalid switch modifier.\n");
return -1;
}
catch (bad_alloc& ba) //If no memory can be allocated in the instantiation of the radio, exception is caught here
{
printf("\n EXCEPTION: Cannot allocate memory.\n");
return -2;
}
catch (bad_exception& e) //Catch exceptions for unknown errors
{
printf("\n EXCEPTION: Unknown Excpetion Error.\n");
return -3;
}
catch (runtime_error& re)
{
printf("\n EXCEPTION: Runtime error\n");
return -4;
}
}
//Shows the currents settings for radio
pRadio->ShowCurrentSettings();
//Gets the user inputed selection
selection = pRadio->GetInput();
//Make the selection setting change (if appilicable)
pRadio->MakeSelection(selection);
//Redisplay the settings in case they had been adjusted
pRadio->ShowCurrentSettings();
//Checks what selection was made and changes the argument to the appropriate syntax
if (selection == 'c')
{
strcpy(arg, "-car");
}
else if (selection == 'a')
{
strcpy(arg, "-am");
}
else if (selection == 'w')
{
strcpy(arg, "-world");
}
//Checks if the previous argument is the same as the current, if not then delete the current object
if (strcmp(previousArg, arg) != 0 || selection == 'x')
{
//Deletes the current object
try
{
delete pRadio;
}
catch (bad_exception& e) //Catches any unexpected exceptions
{
printf("\n EXCEPTION: Unknown Exception\n");
return -5;
}
catch (runtime_error& re)
{
printf("\n EXCEPTION: Runtime error\n");
return -6;
}
}
} while (selection != 'x'); //Exits when user selects 'x'
printf("\nGoodbye!\n");
return 0;
}
PioneerCarRadio * createRadio(char *s)
{
//Variables
PioneerCarRadio * returnPtr = NULL;
//Check if the parameter is there and valid
if (s == NULL)
{
throw s; //throw the parameter
}
else if (strcmp(s, "-car") == 0)
{
//News the PioneerCarRadio and throws the pointer if NULL
if ((returnPtr = new PioneerCarRadio(false)) == NULL)
{
throw returnPtr;
}
else
{
return returnPtr;
}
}
else if (strcmp(s, "-am") == 0)
{
//News the PioneerAM and throws the pointer if NULL
if ((returnPtr = new PioneerAM(false)) == NULL)
{
throw returnPtr;
}
else
{
return returnPtr;
}
}
else if (strcmp(s, "-world") == 0)
{
//News the PioneerWorld and throws the pointer if NULL
if ((returnPtr = new PioneerWorld(false)) == NULL)
{
throw returnPtr;
}
else
{
return returnPtr;
}
}
else
{
throw s;
}
return NULL; //Default return
}
Problem Child (PioneerWorld.h file):
#include <stdio.h>
#include"PioneerAM.h"
//Class
class PioneerWorld : public PioneerAM
{
private:
public:
PioneerWorld(bool power, char *name = (char *)"Pioneer XS440-WLRD") : PioneerAM(power, name)
{
ChangeCurrentStation(531);
}
virtual ~PioneerWorld()
{
printf("Destroying Pioneer XS440-WRLD Radio.\n");
}
virtual void ScanUp()
{
Freqs storedAM = GetStoredFreqs();
//if current_station is 1700, the current_station becomes 530
if (GetCurrentStation() >= 1602)
{
ChangeCurrentStation(531);
storedAM.AMFreq = GetCurrentStation();
}
else
{
ChangeCurrentStation(GetCurrentStation() + 9);
storedAM.AMFreq = GetCurrentStation();
}
}
virtual void ScanDown()
{
Freqs storedAM = GetStoredFreqs();
//if current_station is 1700, the current_station becomes 530
if (GetCurrentStation() <= 531)
{
ChangeCurrentStation(1602);
storedAM.AMFreq = GetCurrentStation();
}
else
{
ChangeCurrentStation(GetCurrentStation() - 9);
storedAM.AMFreq = GetCurrentStation();
}
}
};
The program should run until it is terminated without error and catch any exceptions, but instead if exiting the program at any time after radio was switched to PioneerWorld radio the program will execute normally until the main's return 0; at which point, on the next line (the '}') visual studios comes up with a error:
Unhandled exception at 0x7765806C (ntdll.dll) in A-06.exe: 0xC000000D:
An invalid parameter was passed to a service or function. occurred
This is my first post so if there's anything wrong or you'd like more of the code to better understand what is the problem just ask.
Thanks for the help!

Why my code runs to infinite loop when I input a non integer from scanf? [duplicate]

I've a small C-program which just reads numbers from stdin, one at each loop cycle. If the user inputs some NaN, an error should be printed to the console and the input prompt should return again. On input of "0", the loop should end and the number of given positive/negative values should be printed to the console. Here's the program:
#include <stdio.h>
int main()
{
int number, p = 0, n = 0;
while (1) {
printf("-> ");
if (scanf("%d", &number) == 0) {
printf("Err...\n");
continue;
}
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
My problem is, that on entering some non-number (like "a"), this results in an infinite loop writing "-> Err..." over and over. I guess it's a scanf() issue and I know this function could be replace by a safer one, but this example is for beginners, knowing just about printf/scanf, if-else and loops.
I've already read the answers to the questionscanf() skips every other while loop in C and skimmed through other questions, but nothing really answer this specific problem.
scanf consumes only the input that matches the format string, returning the number of characters consumed. Any character that doesn't match the format string causes it to stop scanning and leaves the invalid character still in the buffer. As others said, you still need to flush the invalid character out of the buffer before you proceed. This is a pretty dirty fix, but it will remove the offending characters from the output.
char c = '0';
if (scanf("%d", &number) == 0) {
printf("Err. . .\n");
do {
c = getchar();
}
while (!isdigit(c));
ungetc(c, stdin);
//consume non-numeric chars from buffer
}
edit: fixed the code to remove all non-numeric chars in one go. Won't print out multiple "Errs" for each non-numeric char anymore.
Here is a pretty good overview of scanf.
scanf() leaves the "a" still in the input buffer for next time. You should probably use getline() to read a line no matter what and then parse it with strtol() or similar instead.
(Yes, getline() is GNU-specific, not POSIX. So what? The question is tagged "gcc" and "linux". getline() is also the only sensible option to read a line of text unless you want to do it all by hand.)
I think you just have to flush the buffer before you continue with the loop. Something like that would probably do the job, although I can't test what I am writing from here:
int c;
while((c = getchar()) != '\n' && c != EOF);
Due to the problems with scanf pointed out by the other answers, you should really consider using another approach. I've always found scanf way too limited for any serious input reading and processing. It's a better idea to just read whole lines in with fgets and then working on them with functions like strtok and strtol (which BTW will correctly parse integers and tell you exactly where the invalid characters begin).
Rather than using scanf() and have to deal with the buffer having invalid character, use fgets() and sscanf().
/* ... */
printf("0 to quit -> ");
fflush(stdout);
while (fgets(buf, sizeof buf, stdin)) {
if (sscanf(buf, "%d", &number) != 1) {
fprintf(stderr, "Err...\n");
} else {
work(number);
}
printf("0 to quit -> ");
fflush(stdout);
}
/* ... */
I had similar problem. I solved by only using scanf.
Input "abc123<Enter>" to see how it works.
#include <stdio.h>
int n, num_ok;
char c;
main() {
while (1) {
printf("Input Number: ");
num_ok = scanf("%d", &n);
if (num_ok != 1) {
scanf("%c", &c);
printf("That wasn't a number: %c\n", c);
} else {
printf("The number is: %d\n", n);
}
}
}
On some platforms (especially Windows and Linux) you can use fflush(stdin);:
#include <stdio.h>
int main(void)
{
int number, p = 0, n = 0;
while (1) {
printf("-> ");
if (scanf("%d", &number) == 0) {
fflush(stdin);
printf("Err...\n");
continue;
}
fflush(stdin);
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
The Solution: You need to add fflush(stdin); when 0 is returned from scanf.
The Reason: It appears to be leaving the input char in the buffer when an error is encountered, so every time scanf is called it just keeps trying to handle the invalid character but never removing it form the buffer. When you call fflush, the input buffer(stdin) will be cleared so the invalid character will no longer be handled repeatably.
You Program Modified: Below is your program modified with the needed change.
#include <stdio.h>
int main()
{
int number, p = 0, n = 0;
while (1) {
printf("-> ");
if (scanf("%d", &number) == 0) {
fflush(stdin);
printf("Err...\n");
continue;
}
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
try using this:
if (scanf("%d", &number) == 0) {
printf("Err...\n");
break;
}
this worked fine for me... try this..
the continue statement is not appropiate as the Err.. should only execute once. so, try break which I tested... this worked fine for you.. i tested....
When a non-number is entered an error occurs and the non-number is still kept in the input buffer. You should skip it. Also even this combination of symbols as for example 1a will be read at first as number 1 I think you should also skip such input.
The program can look the following way.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int p = 0, n = 0;
while (1)
{
char c;
int number;
int success;
printf("-> ");
success = scanf("%d%c", &number, &c);
if ( success != EOF )
{
success = success == 2 && isspace( ( unsigned char )c );
}
if ( ( success == EOF ) || ( success && number == 0 ) ) break;
if ( !success )
{
scanf("%*[^ \t\n]");
clearerr(stdin);
}
else if ( number > 0 )
{
++p;
}
else if ( number < n )
{
++n;
}
}
printf( "\nRead %d positive and %d negative numbers\n", p, n );
return 0;
}
The program output might look like
-> 1
-> -1
-> 2
-> -2
-> 0a
-> -0a
-> a0
-> -a0
-> 3
-> -3
-> 0
Read 3 positive and 3 negative numbers
I had the same problem, and I found a somewhat hacky solution. I use fgets() to read the input and then feed that to sscanf(). This is not a bad fix for the infinite loop problem, and with a simple for loop I tell C to search for any none numeric character. The code below won't allow inputs like 123abc.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(int argc, const char * argv[]) {
char line[10];
int loop, arrayLength, number, nan;
arrayLength = sizeof(line) / sizeof(char);
do {
nan = 0;
printf("Please enter a number:\n");
fgets(line, arrayLength, stdin);
for(loop = 0; loop < arrayLength; loop++) { // search for any none numeric charcter inisde the line array
if(line[loop] == '\n') { // stop the search if there is a carrage return
break;
}
if((line[0] == '-' || line[0] == '+') && loop == 0) { // Exculude the sign charcters infront of numbers so the program can accept both negative and positive numbers
continue;
}
if(!isdigit(line[loop])) { // if there is a none numeric character then add one to nan and break the loop
nan++;
break;
}
}
} while(nan || strlen(line) == 1); // check if there is any NaN or the user has just hit enter
sscanf(line, "%d", &number);
printf("You enterd number %d\n", number);
return 0;
}
To solve partilly your problem I just add this line after the scanf:
fgetc(stdin); /* to delete '\n' character */
Below, your code with the line:
#include <stdio.h>
int main()
{
int number, p = 0, n = 0;
while (1) {
printf("-> ");
if (scanf("%d", &number) == 0) {
fgetc(stdin); /* to delete '\n' character */
printf("Err...\n");
continue;
}
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
But if you enter more than one character, the program continues one by one character until the "\n".
So I found a solution here: How to limit input length with scanf
You can use this line:
int c;
while ((c = fgetc(stdin)) != '\n' && c != EOF);
// all you need is to clear the buffer!
#include <stdio.h>
int main()
{
int number, p = 0, n = 0;
char clearBuf[256]; //JG:
while (1) {
printf("-> ");
if (scanf("%d", &number) == 0) {
fgets(stdin, 256, clearBuf); //JG:
printf("Err...\n");
continue;
}
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
Flush the input buffer before you scan:
while(getchar() != EOF) continue;
if (scanf("%d", &number) == 0) {
...
I was going to suggest fflush(stdin), but apparently that results in undefined behavior.
In response to your comment, if you'd like the prompt to show up, you have to flush the output buffer. By default, that only happens when you print a newline. Like:
while (1) {
printf("-> ");
fflush(stdout);
while(getchar() != EOF) continue;
if (scanf("%d", &number) == 0) {
...
Hi I know this is an old thread but I just finished a school assignment where I ran into this same problem.
My solution is that I used gets() to pick up what scanf() left behind.
Here is OP code slightly re-written; probably no use to him but perhaps it will help someone else out there.
#include <stdio.h>
int main()
{
int number, p = 0, n = 0;
char unwantedCharacters[40]; //created array to catch unwanted input
unwantedCharacters[0] = 0; //initialzed first byte of array to zero
while (1)
{
printf("-> ");
scanf("%d", &number);
gets(unwantedCharacters); //collect what scanf() wouldn't from the input stream
if (unwantedCharacters[0] == 0) //if unwantedCharacters array is empty (the user's input is valid)
{
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
else
printf("Err...\n");
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
I've recently been through the same problem, and I found a solution that might help a lot of people. The function "scanf" leaves a buffer in memory ... and that's why the infinite loop is caused. So you actually have to "store" this buffer to another variable IF your initial scanf contains the "null" value. Here's what I mean:
#include <stdio.h>
int n;
char c[5];
int main() {
while (1) {
printf("Input Number: ");
if (scanf("%d", &n)==0) { //if you type char scanf gets null value
scanf("%s", &c); //the abovementioned char stored in 'c'
printf("That wasn't a number: %s\n", c);
}
else printf("The number is: %d\n", n);
}
}

Reading from Arduino Serial seems to be very unstable

I have the following simple code to read commands sent from the computer to an Arduino Mega board:
void get_command()
{
char received;
int index = 0;
while (Serial.available() > 0) {
if (index < BUFFER_SIZE -1) {
received = Serial.read();
if (received == '\n') {
buffer[index] = '\0';
parse_command(buffer);
} else {
buffer[index++] = received;
}
} else {
Serial.println('666'); // buffer overflow
}
}
}
The commands are like A123 B123 C123 D123\n
Basically a sequence of space separated instructions, were each instruction starts by a letter and follows by a number. A command ends with a "\n".
Reading this seems to be very unstable. Sometimes I get the command perfectly, sometimes I miss the first letter, sometimes a pair of them, sometimes it starts by the number,...
I am sending the commands through the serial monitor, set to newline.
Before having this code, I'd simply check for the size using Serial.available, then Id wait a second to fill the buffer, and then I'd copy the buffer to a char*. This worked flawlessly. I am doing now this loop waiting for a \n, which seems more elegant, but it is being very unstable.
Code works by simply adding a delay(100) after the first Serial.available()
This is the code:
void get_command()
{
char received;
if (Serial.available() > 0) {
delay(100); // let the buffer fill up
int index = 0;
while (Serial.available() > 0) {
if (index < BUFFER_SIZE -1) {
received = Serial.read();
if (received != '\n') {
buffer[index] = received;
index++;
} else {
buffer[index] = '\0';
parse_command(buffer);
}
} else {
Serial.println('666'); // buffer overflow
}
}
}
}