How to get length of an array that is filled with input - c++

I have asked a question here and now the code below makes the work that I expected (the work that I mentioned previously). Now I have another issue: if I write tmp[20] and if the size of the input is 20 chars, the code works. However the size of the input is not known. Therefore, there can be a maxsize, but the actual size depends on the input. How can I make this code work with every length? (yes, the code works when I write 200 inside of tmp but the size of 'message' depends on the whole array. It should be 3 chars before end and 6 chars after start).Therefore when I write 200 inside of tmp[] and the input is shorter than 200 chars, the message returns incorrectly. I think I should use dynamic memory allocation but I could not implement it to my code.
Here is my complete code:
char tmp[20] = { 0 };
int len = sizeof(tmp) / sizeof(tmp[0]);
String pack;
String command;
String Size;
String messum;
String message;
String checksum;
int Index = 0;
bool Seen = false;
void setup() {
Serial.begin(9600);
}
void loop() {
while (Serial.available() > 0) {
char received = Serial.read();
if (received == '!') {
Seen = true;
} else
if (received == '#') {
return strdup(tmp);
} else
if (Seen == true) {
if (Index < 2) {
//Serial.print("P");
pack = tmp[Index++] = received;
Serial.print(pack);
} else
if (Index < 4) {
//Serial.print("C");
command = tmp[Index++] = received;
Serial.print(command);
} else
if (Index < 6) {
//Serial.print("S");
Size = tmp[Index++] = received;
Serial.print(Size);
} else
if (Index < (len - 3)) {
//Serial.print("M");
message = tmp[Index++] = received;
Serial.print(message);
} else
if (Index < len) {
//Serial.print("C");
checksum = tmp[Index++] = received;
Serial.print(checksum);
}
}
}
return NULL;
//input: asdeyh134!123456789abcdefghtry#8647dfn
}

Anywhere you are adding characters to your array like this:
if (Seen == true) {
if (Index < 2) {
//Serial.print("P");
pack = tmp[Index++] = received;
Serial.print(pack);
You should also null terminate your string like so:
if (Seen == true) {
if (Index < 2) {
//Serial.print("P");
pack = tmp[Index++] = received;
tmp[Index] = 0;
Serial.print(pack);
That way you can use strlen to get the length of the string in the array. It will count the number of characters up to that null character.
int length = strlen(tmp);
On the next pass of the loop when you write in another character you will write it over that null and then write a new null right after that new character.

Related

Cannot detect digit in string using isdigit()

The task of this function is to check, whether it contains any symbols but digits, spaces, or minuses.
bool MainWindow::inputExcp()
{
QString inputStr = ui->input->toPlainText();;
QByteArray ba = inputStr.toLocal8Bit();
char *myString = ba.data();
QString warn;
char space = ' ';
size_t size = sizeof(myString);
try{
for(unsigned long long i = 0; i < size; i++)
{
if (isdigit(*(myString+i)))
continue;
else if (*(myString+i) == space)
continue;
else if(*(myString+i) == '-')
continue;
else
throw *(myString+i);
}
}
catch (char x)
{
warn += ("Enter digits, spaces or minuses");
QMessageBox::warning(this, "Uncorrect input",warn);
return false;
}
return true;
}
I can't understand why this function returns true only for arrays that contain 8 and more elements. What is the solution to this problem?
Because the sizeof() function doesnt return the number of elements of a list, it returns the the size of the memory allocated for it.

How to use length of an array in subtraction

My code below is working perfect when I write number or only len inside of it. However, I want to write(len-3) but it again return as if I write len inside of it. How can I solve it??
I get the length of the array by using:
int len = sizeof(tmp)/sizeof(tmp[0]);
The message variable is a String and received is:
char received = Serial.read();
if (Index<(len-3)){
message=tmp[Index++]=received;
Serial.print(message);
}
My aim is when I write dv35!1234567890*asdfqwertyuiopmnbvcx#asdas the code should return the part of it that is between '!' and '#' then during the if else part the code should get some parts of it. However, the last part should return until 3 chars before the array ends. but it did not work properly. it returns all the parts remaining.(As if I write only len inside of it). the length of the input is not stable so the message part changes depending on the length of the whole array. It should return 3 chars before the end.
Here is my whole code:
char tmp[200] = {0};
String pack;
String command;
String Size;
String messum;
String message;
String checksum;
int len = sizeof(tmp)/sizeof(tmp[0]);
int Index = 0;
bool Seen = false;
void setup(){
Serial.begin(9600);
}
void loop(){
while (Serial.available() > 0){
char received = Serial.read();
if (received == '!'){
Seen = true;
}
else if (received == '#'){
return strdup(tmp);
}
else if (Seen == true){
if(Index<2){
//Serial.print("P");
pack=tmp[Index++] = received;
Serial.print(pack);
}
else if(Index<4){
//Serial.print("C");
command=tmp[Index++] = received;
Serial.print(command);
}
else if(Index<6){
//Serial.print("S");
Size=tmp[Index++] = received;
Serial.print(Size);
}
else if (Index<(len-3)){
Serial.print("M");
message=tmp[Index++]=received;
Serial.print(message);
}
}
}
return NULL;
//input: dv35!1234567890*asdfqwertyuiopmnbvcx#asdas
}
there is no need of most of it.
You define the variable tmp in the global and it has constant length. You do not need to calculate the length of it.
For the char array sizeof(char_array) gives you the length of the array as sizeof(char) is by definition 1
Use the correct types. for the sizes use size_t not int

Converting chars to byte representation using C++

What would be the most efficient yet simplest way to convert a char to its unsigned binary representation (bytes where the MSB is 0)? I have a method set up like this:
string AsciiToBinary(char value) {
string binary = "";
int code = value;
while (code > 0) {
if ((code % 2) == 1) {
binary.append("1", 1);
} else {
binary.append("0", 1);
}
code = code / 2;
}
return binary;
}
I am assuming that setting an int to a char sets the char's ASCII value to the int. However, my results do not match the ASCII table. I am implementing this function as follows:
char head = stack.pop();
int code = head; // do not need to parse
string binary;
while (!stack.isEmpty()) {
binary = AsciiToBinary(code);
outfile << binary << endl;
binary.clear();
head = stack.pop();
code = head;
}
I have stored all of the chars in a stack.
Thank you for info and direction.
std::string::append() adds the character onto the end of the string. So you are putting the bits on in the reverse order: the LSB is the first character and vice versa. Try this: binary.insert (0, 1, (code % 2 == 1) ? '1' : '0');
This method works well and is editable for all those interested and learning C++:
using namespace std; // bad for updates
#include <string>
string AsciiToBinary(char value) {
string binary = "";
unsigned int code = value;
unsigned int chk = value;
while (code > 0) {
if ((code & 1) == 1) {
binary.append("1", 1);
} else {
binary.append("0", 1);
}
code = code / 2;
}
reverse(binary.begin(), binary.end());
if (chk < 64) {
binary.insert(0, "00");
} else {
binary.insert(0, "0");
}
return binary;
}

Arduino character array serial

I'm having a little bit of trouble with this bit of code here for my Arduino.
Basically, I'm trying to send in a series of characters, turn it into an character array, and use that to run the rest of the program. I'm close because I know everything is working perfectly internally, but when I boot from the serial port, the message isn't getting in.
I assume that at this point it probably is how I am constructing the array... or some oddity. It is probably just a simple error in how I put the code together, but I'm completely struck. (I was previously using a string, but because of how the Arduino works with them, it pretty much makes using them for memory purposes impossible.)
I'm using a Java program (Ardulink) to send the information into the program with a customized version I've edited. So simply put, the input has to be a series of characters, and I need it stored in an array.
void serialEvent()
{
int arrayPostion = 0;
int i;
int maxArraySize = 20;
char CharArrayInLocal[20];
while (Serial.available() && !stringComplete)
{
char inChar = (char)Serial.read();
CharArrayInLocal[arrayPostion] = inChar;
arrayPostion++;
if (inChar == '\n')
{
stringComplete = true;
}
}
for (int i = 0; i<=19; i++)
{
CharArrayIn[i] = CharArrayInLocal[i];
}
}
This worked for me,
String CharArrayInLocal[20];
String inputString = "";
boolean stringComplete = false;
int i = 0;
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == '\n') {
CharArrayInLocal[i] = inputString;
i++;
stringComplete = true;
inputString = "";
}
else {
inputString += inChar;
}
}
}

How do I store a stream of characters in an array?

I have a stream of characters coming over the serial port like this;
FILE1,FILE2,FILE3,
I'm trying to read them in like this;
char* myFiles[20];
boolean done = false;
int fileNum = 0;
int charPos = 0;
char character;
while (!done)
{
if (Serial.available())
{
character = Serial.read();
if ((character == '\n') || (character == '\r'))
{
done = true;
}
else if (character == ',')
{
myFiles[fileNum][charPos] = '\0';
fileNum++;
charPos = 0;
}
else
{
myFiles[fileNum][charPos] = character;
charPos++;
}
}
}
when I try to print the first value like this;
Serial.println(myFiles[0]);
i get a continuous stream of characters.
What am i doing wrong?
What you are doing wrong is not allocating any memory for your strings.
Here's one way to do this
#include <vector>
#include <string>
std::vector<std::string> myFiles;
std::string file;
bool done = false;
char character;
while (!done)
{
if (Serial.available())
{
character = Serial.read();
if ((character == '\n') || (character == '\r'))
{
done = true;
}
else if (character == ',')
{
myfiles.push_back(file);
file = "";
}
else
{
file += character;
}
}
}
Serial.println(myFiles[0].c_str());
Since you are programming in C++ you should learn how to use std::vector and std::string, they will save you a lot of grief.
If std::vector and std::string are not available to you (apparently so on Arduino) then the quick hack would be to preallocate a fixed amount of memory for your strings by replacing
char* myFiles[20];
with
char myFiles[20][100];