mbed application board lcd screen button control - c++

#include "mbed.h"
#include "C12832_lcd.h"
#include<cstring>
#include<string>
#include<sstream>
C12832_LCD lcd;//creating LCD object
Serial s_comms(USBTX, USBRX);//creating a serial comms object
DigitalIn Button(p14);//using button to change pages
int main()
{
char str[100] = "$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A";
char*point;
point = strtok(str, ",");
int page_state = 0;
for (int i = 0; point != NULL; i++){
//time
if (i == 1 and page_state == 0){
//using substrings to extract time elements
string time = point;
string hrs = time.substr(0, 2);
string mins = time.substr(2, 2);
string sec = time.substr(4, 2);
//using string streams to reformat time string
ostringstream tim;
tim << hrs << ":" << mins << ":" << sec;
time = tim.str();
lcd.cls();
lcd.locate(0, 1);
lcd.printf("%s\n", time.c_str());
}
//date
if (i == 9 and page_state == 0){
string date = point;
string day = date.substr(0, 2);
string month = date.substr(2, 2);
string year = date.substr(4, 2);
//Converting the numerical month into abbreviation ect.
if (month == "03"){
month = "Mar";
}
if (month == "04"){
month = "Apr";
}
ostringstream dat;
dat << day << "-" << month << "-20" << year;
date = dat.str();
lcd.locate(0, 9);
lcd.printf("%s\n", date.c_str());
}
//latitude
if (i == 3 and page_state == 0){
string lati = point;
string lati_deg = lati.substr(0, 2);
string sml_latideg = lati.substr(2, 6);
ostringstream lat;
lat << "Lat: " << lati_deg << " deg " << sml_latideg << "'";
lati = lat.str();
lcd.locate(0, 18);
lcd.printf("%s", lati.c_str());
}
//latitude direction (N or S)
if (i == 4 and page_state == 0){
string lat_dir = point;
lcd.printf("%s\n", lat_dir.c_str());
}
point = strtok(NULL, ",");
}
//Change page
if (Button == 1){
page_state = !page_state;//toggle page state
wait(0.2);//debounce timer
lcd.cls();
}
//second page
for (int j = 0; point != NULL; j++){
char str[100] ="$GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A";
char*point;
point = strtok(str, ",");
//longitude
if (j == 5 and page_state == 1){
string lngi = point;
string lngi_deg = lngi.substr(0, 2);
string sml_lngideg = lngi.substr(2, 6);
ostringstream lng;
lng << "Lng: " << lngi_deg << " deg " << sml_lngideg << "'";
lngi = lng.str();
lcd.locate(0, 1);
lcd.printf("%s", lngi.c_str());
}
//longitude direction (E or W)
if (j == 6 and page_state == 1){
string lng_dir = point;
lcd.printf("%s\n", lng_dir.c_str());
}
//speed
if (j == 7 and page_state == 1){
string speed = point;
ostringstream spd;
spd << "Speed: " << speed;
speed = spd.str();
lcd.locate(0, 9);
lcd.printf("%s\n", speed.c_str());
}
point = strtok(NULL, ",");
}
return 0;
}
hello, trying to get the onboard button on an mbed application board to allow me to clear the screen and put new info, the button currently does nothing, i am getting the first 4 parts of info on the screen however this does not change when the button is pressed, i need help to try to make this work

This does not directly answer OP's question, but this should be more helpful in the long run. Rather than trying to debug the program logic in a limited environment it is often helpful to replace the platform-specific functionality with functions and classes that allow simulation of of the platform on general purpose computing hardware without having to change the code.
By adding
#include <cstdarg>
#include <iostream>
and a fake C12832_lcd.h
#pragma once
#include <cstdarg>
#include <iostream>
// Sim LCD class. Just writes LCD commands to console
class C12832_LCD
{
public:
void cls()
{
std::cout << "LCD: Cleared" << std::endl;
}
void locate(int row, int col)
{
std::cout << "LCD: positioned " << row << "," << col << std::endl;
}
void printf(const char * fmt, ...)
{
char buffer[4096];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
std::cout << buffer << std::endl;
va_end(args);
}
};
And a bogus mbed.h
#pragma once
// Sim DigitalIn class. Toggles true and false on the button. First call will be true
class DigitalIn
{
private:
bool mVal;
public:
DigitalIn(int): mVal(false)
{
}
bool operator==(int)
{
mVal = !mVal;
return mVal;
}
};
//Sim serial Does nothing yet.
class Serial
{
public:
Serial(int, int)
{
}
};
//sim wait. We don't need to wait in simulation, so does nothing.
void wait(double)
{
}
const int p14 = 14;
const int USBTX = 0;
const int USBRX = 0;
to OP's code, I can now compile and run on the desktop in the Visual Studio IDE and throw the awesome might of the debugger at the problem. Stepping through the code quickly reveals the first of two logic errors. The second one is a bit more subtle. Watch your scope.
A quick recommendation:
Rather than using strtok, consider using the std::getline overload that takes a character delimiter. This allows
std::stringstream stream(str);
std::string token;
while (std::getline(stream, token, ','))
{
// do stuff
}
to read through a comma separated stream of input like a NMEA string.

Related

Jump to a specific vector place if a condition is met and start reading it from there

We need to create a universal Turing machine.
We have a file with the provided information: tape count, starting input, starting position and the rules.
Reading from the file isn't that big of a problem. What I'm doing right now is creating a structure vector and reading all the rules to there.
What I can't figure out is how to make the machine itself work. We know that the starting state is always zero, so I'm starting from there. Looking for the rules that start with this state, but what I cannot figure out is what if I have to jump back to the first rules? What to do then? What can of counting mechanism for the vector can I implement? I'm really new to vectors. I'll add that for the algorithm itself.
No more than two loops can be used, not counting printing out text or reading from the file.
The code I have right now is:
#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <Windows.h>
struct rule {
std::string qstate; // dabartine busena
char csymbol; // dabartinis simbolis
char nsymbol; // naujasis simbolis
char direction; // i kuria puse eis galvute
std::string nstate; // naujoji busena
};
void printingText(std::vector<char> input, int position, long long steps);
void searchingForASymbolOrState(std::vector<rule> rules, std::vector<char> input, std::string state, int position, int& cursorPos);
int main()
{
int tapeCount, position;
long long steps = 0;
std::string tape;
std::ifstream file("1.txt");
file >> tapeCount >> tape >> position;
std::vector <char> input(tape.begin(), tape.end());
std::vector <rule> rules;
rule temp;
while (file >> temp.qstate) {
file >> temp.csymbol;
file >> temp.nsymbol;
file >> temp.direction;
file >> temp.nstate;
rules.push_back(temp);
}
file.close();
position--; // kadangi masyvas skaiciuoja nuo nulio, tai ir startine pozicija sumazinu, kadangi ji skaiciuoja nuo vieno
int cursorPos = 0; // saugosim vieta, kurioje vietoje prasideda taisykles su reikiama busena
std::string state = "0"; // saugosim busena, kad zinotume, kokioje busenoje siuo metu esame
// Tiuringo masinos "algoritmas"
while (true) {
printingText(input, position, steps);
if (state == rules[cursorPos].qstate) {
if (input[position] == rules[cursorPos].csymbol) {
if (input[position] != rules[cursorPos].nsymbol) {
input[position] = rules[cursorPos].nsymbol;
if (rules[cursorPos].direction == 'L') {
position--;
steps++;
}
else if (rules[cursorPos].direction == 'R') {
position++;
steps++;
}
if (rules[cursorPos].nstate != state) {
state = rules[cursorPos].nstate;
}
}
else if (input[position] == rules[cursorPos].nsymbol) {
if (rules[cursorPos].direction == 'L') {
position--;
steps++;
}
else if (rules[cursorPos].direction == 'R') {
position++;
steps++;
}
if (rules[cursorPos].nstate != state) {
state = rules[cursorPos].nstate;
}
}
}
else if (input[position] != rules[cursorPos].csymbol) {
searchingForASymbolOrState(rules, input, state, position, cursorPos);
}
}
else if (state != rules[cursorPos].qstate) {
searchingForASymbolOrState(rules, input, state, position, cursorPos);
} // Skaiciuojam zingsnius
// std::cout << cursorPos << " " << position << " " << state << " " << rules[cursorPos].qstate; // Eilute naudojama klaidu paieskai
Sleep(100);
system("cls");
}
// "Algoritmo pabaiga"
}
void printingText(std::vector<char> input, int position, long long steps) {
std::cout << "Head position can be seen with '' symbols\n\n";
for (int i = 0; i < input.size(); i++) {
if (i == position) {
std::cout << "'" << input[i] << "'";
}
else {
std::cout << input[i];
}
}
std::cout << "\n\nSteps: " << steps;
}
void searchingForASymbolOrState(std::vector<rule> rules, std::vector<char> input, std::string state, int position, int& cursorPos) {
for (int i = 0; i < rules.size(); i++) {
if (rules[i].qstate == state) {
if (rules[i].csymbol == input[position]) {
cursorPos = i;
}
}
if (rules[cursorPos].qstate != state) {
if (rules[i].qstate == state) {
cursorPos = i;
}
}
}
}
I know that either .eof() or system("cls") aren't good functions to use, but for this project, I think they'll work fine. Correct me if I'm wrong.
EDIT: I tried to do something. Not sure if there's a more effective why. Obviously it's not finished, no halting and error checking and etc. But if you have any comments, they would be really appreciated.

Logic for the string to not fall in the middle of another string

I need help in figuring out the logic or code to when I want my string not to fall in the middle of another string. For example my given word is "Birthday!" and the other string to look for it is "Happy Birthday Scott". It's going to return a false value because it's missing an exclamation point. Here is the code that I've worked
int Words::matchWords(const char* string, const char* sentence, int wordNum){
int wordCount = words(sentence); // the words function counts the number of words in the sentence
int strLength = strlen(str);
int sentLength = strlen(sentence);
int i = 0;
char strTemp[100];
char sentenceTemp[100];
strcpy(strTemp, str);
strcpy(sentenceTemp, sentence);
if (wordNum > wordCount) {
return false;
}
char* temp;
for (i = 0; i < strLength; i++) {
strTemp[i] = tolower(str[i]);
}
for (i = 0; i < sentLength; i++) {
sentenceTemp[i] = tolower(str[i]);
}
temp = strstr(sentenceTemp, strTemp);
if (temp != NULL) {
return true;
if (strTemp[i] != sentenceTemp[i]) {
return false;
}
else
return true;
}
else
return false;
}
Here is a super simple program for you to look at.
All you have to do for this problem is create your strings using std::string, determine if they are inside the big string using find(), and lastly check if it was found using string::npos.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string bday = "Birthday!";
string str1 = "Happy Birthday Scott";
int found1 = str1.find(bday);
string str2 = "Scott, Happy Birthday!";
int found2 = str2.find(bday);
if (found1 == string::npos) //if Birthday! is NOT found!
{
cout << "str1: " << "FALSE!" << endl;
}
if (found2 != string::npos) //if Birthday! IS found!
{
cout << "str2: " << "TRUE!" << endl;
}
}
Note that for string::npos, you use == for something NOT being found and != for something that IS found.

Making a Caesar Cypher, and it does not want to decipher the message

For a project, we have to make a Caesar Cipher using classes and save the encrypted message inside of a file so a user can decipher it with the program.
I input the message and it has no problem encrypting the message according to the displacement/key I input (since I gave an option for the user to place the displacement they please).
However, the problem lies in decripting the message. It seems to only decript the penultimate or last letter of what I inputted and it doesnt even bother to show the remaining characters of the message.
I have currently no idea why its acting the way it is, I figured I would have to change the message to take char variables instead of string, but that would mean rewriting a large chunk of the code, and at the moment, I would like to avoid having to rewrite the code from scratch. If there are no other options, then I guess I will have to rewrite the code.
Here is the code, (hope that helps and sorry if my message may seem messy, this is the first time I post anything here):
#include<iostream>
#include<string>
#include<fstream>
#include<ctime>
#include<cstdlib>
/* This is a program that will grab a message from the user and encrypt it, then decrypt it
It will also generate a random 8-digit character password used to access the encrypted file
It will also have the ability to allow the user to choose how many spaces the cipher will take into account */
using namespace std;
//Implement a set displacement and get displacement
class Cipherer
{
private:
int displacement;
string message;
//string decryptMessage;
public:
void setDisplacer(int key);
int getDisplacer()const;
void msgEncripter(string, int);
string getMessage()const;
void msgDecripter(string);
string getDecription()const;
};
void Cipherer::setDisplacer(int key)
{
displacement = key;
}
int Cipherer::getDisplacer()const
{
return displacement;
}
void Cipherer::msgEncripter(string msg, int key)
{
string encriptedMsg = msg;
//.size returns the number of elements
for (unsigned int i = 0; i < msg.size(); i++)
{
if (msg[i] == 32) //32 is the value in ASCII of the space character
{
continue;
}
else
{
if ((msg[i] + key) > 122)
{
int temp = (msg[i] + key) - 122;
encriptedMsg[i] = 96 + temp;
}
else if (msg[i] + key > 90 && msg[i] <= 96)
{
int temp = (msg[i] + key) - 90;
encriptedMsg[i] = 64 + temp;
}
else
{
encriptedMsg[i] += key;
}
}
}
message = encriptedMsg;
}
string Cipherer::getMessage()const
{
return message;
}
void Cipherer::msgDecripter(string msg)
{
string decriptedMsg;
for (unsigned int i = 0; i < msg.size(); i++)
{
if (msg[i] == 32)
{
continue;
}
else
{
if ((msg[i] - displacement) < 97 && (msg[i] - displacement) > 90)
{
decriptedMsg[i] = (msg[i] - displacement) + 26;
}
else if ((msg[i] - displacement) < 65)
{
decriptedMsg[i] = (msg[i] - displacement) + 26;
}
else
{
decriptedMsg = msg[i] - displacement;
}
}
}
message = decriptedMsg;
}
string Cipherer::getDecription()const
{
return message;
}
static const char PASSWORD_POOL[] =
"0123456789";
int poolSize = sizeof(PASSWORD_POOL) - 1;
char getRandChar()
{
return PASSWORD_POOL[rand() % poolSize];
}
int main()
{
srand(time(0));
string pass, input, msg;
int key;
Cipherer message;
ofstream outputFile;
ifstream inputFile;
outputFile.open("SecretMSG.txt");
cout << "Write a message: \n";
getline(cin, msg);
cout << "Choose the displacement of the message (0-25): ";
cin >> key;
message.setDisplacer(key);
message.msgEncripter(msg, key);
outputFile << msg;
outputFile.close();
for (int count = 0; count < 1; count++)
{
for (int i = 0; i <= 7; i++)
{
pass += getRandChar();
}
cout << pass << endl;
}
cout << "Input password " << pass << " ";
cin >> input;
if (input == pass)
{
//Make a local variable to read file
string encryptedMessage;
inputFile.open("SecretMSG.txt");
inputFile >> encryptedMessage;
inputFile.close();
cout << message.getMessage() << endl;
cout << "If you wish to decrypt the message, type in the password once again " << pass << ": ";
cin >> input;
if (input == pass)
{
message.msgDecripter(encryptedMessage);
cout << message.getDecription() << endl;
}
else
{
exit(EXIT_FAILURE);
}
}
else
{
exit(EXIT_FAILURE);
}
system("pause");
return 0;
}
In msgDecripter your string decriptedMsg creates a string with the size 0, so any decriptedMsg[i] = is undefined behavior.
In your msgEncripter you write string encriptedMsg = msg;, and because you create a copy of mgs the encriptedMsg has the same size.
So either you do string decriptedMsg = msg or string decriptedMsg = std::string(msg.size(), ' ');
But a more c++ like approach would be to use transform.
string encriptedMsg = msg;
std::transform(encriptedMsg.begin(), encriptedMsg.end(), encriptedMsg.begin(),
[](unsigned char c) -> unsigned char {
if( c == ' ') {
return c;
} else {
// ... your other encrypting logic ...
}
});
Or using msg as source and an empty string as target and utilize std::back_inserter.

How to convert formatted string HH:MM:SS to seconds in C++

I want to convert a string time stamp formatted in HH:MM:SS to seconds only, and then compare it with a number. I have written a prime version of my code in Java, however I separately ask from Scanner as opposed to having a string time. I'm not much familiar with C++ libraries, as I'm a Java guy. Wondering how I can do it in C++?
Make it brief, String s = "1:01:01"; and String s2= "3600"; I need to know if (s>s2)
import java.util.*;
public class Test {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
int hours;
int mins;
int secs;
System.out.println("Enter Hours: ");
hours = console.nextInt();
System.out.println("Enter Minutes: ");
mins = console.nextInt();
System.out.println("Enter Seconds: ");
secs = console.nextInt();
int showSecs = (hours * 3600) + (mins * 60) + secs;
System.out.println(hours + ":" + mins + ":" + secs + " in secs are "
+ showSecs);
}
}
I'll risk the downvotes and remind you that we still have sscanf in our toolbox.
int h, m, s= 0;
std::string time ="10:40:03"
if (sscanf(time.c_str(), "%d:%d:%d", &h, &m, &s) >= 2)
{
int secs = h *3600 + m*60 + s;
}
As #ghostofstandardspast suggested you can use the std::get_time() I/O manipulator to read a specific time format from a std::istream
#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <ctime>
int main() {
std::tm t;
std::istringstream ss("1:01:01");
ss >> std::get_time(&t, "%H:%M:%S");
std::cout << "Total seconds: "
<< t.tm_hour * 3600 + t.tm_min * 60 + t.tm_sec
<< std::endl;
}
Here's a fully working sample using clang. Unfortunately I couldn't get this sample running using GCC 4.8.x, I'd guess it's not complete in this implementation. May be GCC 4.9.x supports this correctly.
As looking for an alternative (if you can't use a compiler supporting the complete current c++11 standard actually), you may either consider to use std::sscanf() as #Roddy suggested, or split the string using ':' as delimiter character, and simply convert the split out parts to integer values, using the e.g. the atoi() method.
Here's the alternative
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
std::vector<std::string> &split
( const std::string &s
, char delim
, std::vector<std::string> &elems)
{
std::istringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
int main() {
std::vector<std::string> parts;
split("1:01:01",':',parts);
if(parts.size() == 3) {
int hour = std::atoi(parts[0].c_str());
int min = std::atoi(parts[1].c_str());
int sec = std::atoi(parts[2].c_str());
std::cout << "Total seconds: "
<< hour * 3600 + min * 60 + sec
<< std::endl;
}
return 0;
}
Let's do a simple automaton that parse your string:
#include <string>
int string2sec(const std::string& str) {
int i = 0;
int res = -1;
int tmp = 0;
int state = 0;
while(str[i] != '\0') {
// If we got a digit
if(str[i] >= '0' && str[i] <= '9') {
tmp = tmp * 10 + (str[i] - '0');
}
// Or if we got a colon
else if(str[i] == ':') {
// If we were reading the hours
if(state == 0) {
res = 3600 * tmp;
}
// Or if we were reading the minutes
else if(state == 1) {
if(tmp > 60) {
return -1;
}
res += 60 * tmp;
}
// Or we got an extra colon
else {
return -1;
}
state++;
tmp = 0;
}
// Or we got something wrong
else {
return -1;
}
i++;
}
// If we were reading the seconds when we reached the end
if(state == 2 && tmp < 60) {
return res + tmp;
}
// Or if we were not, something is wrong in the given string
else {
return -1;
}
}
This has not been tested so there is no warranties.
EDIT: I still can not promise anything but I ran quick tests and it seems to work properly as expected.
#include <iostream>
int main(int argc, char** argv) {
(void) argc;
(void) argv;
std::cout << string2sec("0:2:0") << std::endl;
std::cout << string2sec("1:0:0") << std::endl;
std::cout << string2sec("1:2:0") << std::endl;
std::cout << string2sec("10:10:10") << std::endl;
return 0;
}
Output:
120
3600
3720
36610

ReadProcessMemory trouble not updating

This program does work at start, but than goes wrong after few loops
I am having trouble with ReadProcessMemory. It works at beginning of my program and reads in large string, but than it stops updating the values correctly. For example it will keep the previous string and stay with that string for rest of program or it will have completely nothing in the string until I shut program off. This happens at random times after first two times it works. The basic address contains a string of text of an item through hover effect in game. However readprocessmemory seems to stop working after few times and I have double checked that the address is still updating the correct values through cheat engine and it is but it is not updating correctly in program. I know code is badly written and I should use vectors etc...
The Problem occurs here:
while(temp.size() < 150 ){
do{
// memset(&buffer[0], 0, sizeof(buffer));
ReadProcessMemory(hProcHandle, (LPCVOID)myaddr, &buffer, sizeof(buffer), NULL);
temp = std::string((char*)buffer);
}
while(temp == previous);
std:: cout << temp.size() << std::endl;
}
The above code was not a loop before, I tried recalling it again until it has new value or not null,however once the program stops working with bad values it just remains stuck in loop no matter how many times I call it, but the same address in cheat engine is being updated at same time, I have double checked that. The main problem in this loop is that readprocessmemory continues to have the same value as previous call and stays that way until shut down the program. The address is being updated in game at same time this is running.
#include <iostream>
#include <Windows.h>
#include <string>
#include <ctime>
#include <sstream>
#include <algorithm>
#include <vector>
DWORD ariaBase = 0x400000 + 0x009B5A20;
std::string teatime[] = {" + 5 E"," + 6 Acc"," + 5 Acc"," + 6 Acc"," + 5 Acc"," + 7 Crit"," + 6 Damage"," + 5 Damage"," + 4 Damage"," + 3 Crit"};
unsigned char* buffer[800] = {0};
std::string temp = "";
std::string previous = "";
int myaddr = 0;
bool match[5];
DWORD aOffset[] = {0x724, 0x37C, 0x0, 0xAC, 0x50};
int count = 0;
std::vector<std::string> stats;
bool statsFound = false;
void WriteToMemory(HANDLE hProcHandle){
stats.clear();
temp = "";
while(temp.size() < 150 ){
do{
// memset(&buffer[0], 0, sizeof(buffer));
ReadProcessMemory(hProcHandle, (LPCVOID)myaddr, &buffer, sizeof(buffer), NULL);
temp = std::string((char*)buffer);
}
while(temp == previous);
std:: cout << temp.size() << std::endl;
}
previous = temp;
std::replace( temp.begin(), temp.end(),(char)'\\', '*');
stats = findStats(temp);
//for( std::vector<std::string>::const_iterator i = stats.begin(); i != stats.end(); ++i)std::cout << *i << ' ' << std::endl;
}
int main(){
...code...
...code...
...code...
...code...
while(statsFound == false){
round++;
checkItem();
Sleep(2000);
WriteToMemory(hProcHandle);
std::cout << round << std::endl;
for( std::vector<std::string>::const_iterator i = stats.begin(); i != stats.end(); ++i)std::cout << *i << ' ' << std::endl;
for(int i = 0; i < stats.size();i++){
for(int j = 0; j < 10;j++){
if(("Identified Attribute:" + teatime[j]) == stats[i])match[i] = true;
}
}
count = 0;
for(int i = 0; i < stats.size();i++){
if(match[i] != true)statsFound = false;
else count++;
if(count == stats.size())statsFound = true;
}
match[0] = false;
match[1] = false;
match[2] = false;
match[3] = false;
if(statsFound == false)MouseStart();
}
...code...
...code...
...code...
}
Can you say what resides in the memory of the target process from which you're reading the data?
Have you heard about GetLastError function? Call it immediately after ReadProcessMemory returns and that may give a clue.