In the Arduino IDE, why does the second call of a function change the previous call results? - function

I tried to write a function that converts a string of hex values into a string of Unicode UTF-8 characters. When this function is called once, everything is fine. But when the function is called twice in succession with the same or different arguments, both output strings are meaningless.
void HEX2String(String* HEXstr, String* str) {
String s2 = "", s3 = "";
long c, c1, c0;
char ch[2] = { 0 };
for (int i = 0; i <= HEXstr->length() - 4; i = i + 4) {
s2 = HEXstr->substring(i, i + 1) + "x" + HEXstr->substring(i + 1, i + 4);
c = (hex2long(&s2));
if (c < 255)
*str += String((char)c);
else {
c1 = (128 + (c & B111111));
c0 = (192 + (c >> 6));
ch[1] = c1;
ch[0] = c0;
str->concat(ch);
}
}
}
String str1 = "0628064700200646062706450020062E062F0627000A0633064406270645000A064806310648062F0020062806470020063306CC0633062A06450020062A064806330637";
String str = "0628064700200646062706450020062E062F0627000A0633064406270645000A064806310648062F0020062806470020063306CC0633062A06450020062A064806330637000A00730061006C0061006D0020006200610072002000730068006F006D0061";
String msg = "";
void setup() {
Serial.begin(9600);
//First call
HEX2String(&str, &msg);
Serial.println(msg);
msg = "";
//Second call
HEX2String(&str1, &msg);
Serial.println(msg);
}
void main() {
//
}
If I comment the second call, the output in the serial monitor is:
سلام
ورود به سیستم توسط
salam bar shoma
It is correct. If the second call is not commented, the output in the serial monitor is:
ب⸮⸮ه⸮⸮ ن⸮⸮ا⸮⸮م⸮⸮ خ⸮⸮د⸮⸮ا⸮⸮
س⸮⸮ل⸮⸮ا⸮⸮م⸮⸮
و⸮⸮ر⸮⸮و⸮⸮د⸮⸮ ب⸮⸮ه⸮⸮ س⸮⸮ی⸮⸮س⸮⸮ت⸮⸮م⸮⸮ ت⸮⸮و⸮⸮س⸮⸮ط⸮⸮
salam bar shomaب⸮⸮ه⸮⸮ ن⸮⸮ا⸮⸮م⸮⸮ خ⸮⸮د⸮⸮ا⸮⸮
س⸮⸮ل⸮⸮ا⸮⸮م⸮⸮
و⸮⸮ر⸮⸮و⸮⸮د⸮⸮ ب⸮⸮ه⸮⸮ س⸮⸮ی⸮⸮س⸮⸮ت⸮⸮م⸮⸮ ت⸮⸮و⸮⸮س⸮⸮ط⸮⸮

C-strings need to be null terminated. Your ch is not.
Define it as 3 characters:
char ch[3] = { 0 };
and add a null terminator:
ch[0] = c0;
ch[1] = c1;
ch[2] = 0;

Related

ion-input type number becomes unresponsive when holding down the delete key on device

I'm having an issue with an ion-input, which drops this error below when holding down the delete key.
"Error: Invalid argument '' for pipe 't'
at new Error (native)
at Error.v (file:///android_asset/www/build/polyfills.js:3:4864)
at e [as constructor] (file:///android_asset/www/build/main.js:94:11171)
at new e (file:///android_asset/www/build/main.js:14:10469)
at n (file:///android_asset/www/build/main.js:9:10302)
at t.transform (file:///android_asset/www/build/main.js:9:11000)
at file:///android_asset/www/build/main.js:1:17764
at e.detectChangesInternal (file:///android_asset/www/build/main.js:125:10032)
at e.t.detectChanges (file:///android_asset/www/build/main.js:4:8847)
at e.t.internalDetectChanges (file:///android_asset/www/build/main.js:4:8640)
at e.detectChangesInternal (file:///android_asset/www/build/main.js:120:27362)
at e.t.detectChanges (file:///android_asset/www/build/main.js:4:8847)
at t.detectChangesInNestedViews (file:///android_asset/www/build/main.js:4:28534)
at e.detectChangesInternal (file:///android_asset/www/build/main.js:80:24234)
at e.t.detectChanges (file:///android_asset/www/build/main.js:4:8847)", source: file:///android_asset/www/build/main.js (29)
This one below is my ion-input:
<ion-input color="primary_light" [(ngModel)]="montco_ui" type="number
(keyup)="formataNumero()"></ion-input>
Also, I'm using this algorithm to handle 2 decimal places, which is working fine, since I guess the issue is related to the type number property on the ion-input.
formataNumero(separador: string = '.', decimais: number = 2) {
console.log('formataNumero called');
let a: any = this.montco_ui.split('');
let ns: string = '';
a.forEach((c: any) => { if (!isNaN(c)) ns = ns + c; });
ns = parseInt(ns).toString();
if (ns.length < (decimais + 1)) {
ns = ('0'.repeat(decimais + 1) + ns);
ns = ns.slice((decimais + 1) * -1);
}
let ans = ns.split('');
let r = '';
for (let i = 0; i < ans.length; i++)
if (i == ans.length - decimais) {
r = r + separador + ans[i]; else r = r + ans[i];
}
this.montco_ui = r;
}
Finally, this is the variable that keeps the value:
P.S.: I'm using Ionic 2 for my project.
public montco_ui: string = "0.00";

Refer to json individual objects in cpp crow

i am using a cpp crow library and i am having difficulty in accessing individual objects i am attaching my code here.
CROW_ROUTE(app,"/hello/<string>")
([](string name){
crow::json::wvalue x;
x["name"] = "llllds";
x["Town"] = "Texas";
x["nickname"] = "drax";
x["father"] = "Nethan";
if (name == "Nothing")
cout << "Bad Responce";
std::ostringstream os;
cout << name << " is the required query";
val = x[name];
return val;
And i want to return my name can anyone help me with this. Thanks in advance
I used JSON for Modern C++ within crow (https://github.com/nlohmann/json)
Here is an example CROW_ROUTE I wrote
CROW_ROUTE(app, "/palindromes/<string>/<string>")([](const request &req, response &res, string ID, string words){
palindromeHash.insert({ID, words}); //ignore this
nlohmann::json x;
x = getPalindromes(palindromeHash.at(ID));
palindromeHash.erase(ID); //ignore this
res.sendJSON(x);
});
//getPalindromesFunction()
nlohmann::json getPalindromes(string data){
nlohmann::json x;
unordered_map<string, bool> hashmap;
string word = "";
std::string::size_type i = data.find("%20");
while (i != std::string::npos){
data.erase(i, 3);
data.insert(i, " ");
i = data.find("%20", i);
}
for(int i = 0; i < data.size(); i++){
if(data[i] == ' '){
hashmap.insert({word, true});
word = "";
}
else{
word += data[i];
}
}
string temp;
vector<string> words;
int numValid = 0;
for(auto& i: hashmap){
temp = i.first;
reverse(temp.begin(), temp.end());
auto got = hashmap.find(temp);
if(got != hashmap.end()){
words.push_back(i.first);
numValid++;
}
}
x["words"] = words;
x["numValid"] = numValid;
return x;
}
As you can see it returns a JSON object x that holds palindromes. The sendJSON() function is something I added to crow_all.h. Add it under the struct response section on line 7215
void sendJSON(const nlohmann::json& data){
std::string response = data.dump();
add_header("Access-Control-Allow-Origin", "*");
add_header("Content-Type", "text/html");
write(response);
end();
}
Remember to include "json.h" in both main.cpp and crow_all.h. The res.sendJSON will send it to my JS file which can loop through the JSON with ease.
$.get("/palindromes/" + ID + "/" + curr_line, {}, function(response){
let x = JSON.parse(response); //This will allow JS to read the C++ JSON
for(let i = 0; i < x.words.length; i++){
term.write(x.words[i] + "\r\n");
}
}

how to get real direction steps using Flutter? (draw real route)

I'm working with taxi app. Is it possible to draw real route on real road using flutter?
I used this way: https://developers.google.com/maps/documentation/directions/intro#ExampleRequests
getDirectionSteps(double destinationLat, double destinationLng) {
network
.get("origin=" +
location.latitude.toString() +
"," +
location.longitude.toString() +
"&destination=" +
destinationLat.toString() +
"," +
destinationLng.toString() +
"&key=api_key")
.then((dynamic res) {
List<Steps> rr = res;
print(res.toString());
ccc = new List();
for (final i in rr) {
ccc.add(i.startLocation);
ccc.add(i.endLocation);
}
mapView.onMapReady.listen((_) {
mapView.setMarkers(getMarker(location.latitude,location.longitude,destinationLat,destinationLng));
mapView.addPolyline(new Polyline("12", ccc, width: 15.0));
});
_screenListener.dismissLoader();
showMap();
}).catchError((Exception error) => _screenListener.dismissLoader());
}
my output look like this:
But I need like this: (draw destination route on real road)
to find the exact route you have to get points out of the polylineoverview from the json from directions api.
This is how I extracted the exact route just like you show in the second image.
Its is a function that return points as a string
Future<String> getRouteCoordinates(LatLng l1, LatLng l2) async {
String url =
"https://maps.googleapis.com/maps/api/directions/json?origin=${l1.latitude},${l1.longitude}&destination=${l2.latitude},${l2.longitude}&key=${Constants.anotherApiKey}";
http.Response response = await http.get(url);
Map values = jsonDecode(response.body);
ProjectLog.logIt(TAG, "Predictions", values.toString());
return values["routes"][0]["overview_polyline"]["points"];
}
you will get a string of points somewhat similiar to this
u|umDs`gwML}A_GGgFGAWwDEm#TcFGsAAa#BeA\QDe#AYISOKHKJGFw#^?jAAnAEnOA|GAhHEx#?jA#tC?XFLLf#Bf##t#?xAA|E?dEEj_#GxMChG#tCIvl##tAK`DQlA?zBApE?lBExNAlH#rMAtGJdDJnATfB`AnEdAzEj#~B|#lEF\xAvGnAlF~#lEv#`DvAxFxAxGzCdN`H`ZnEnRr#hDnB|IhDlNvKnd#vDhPrFzUzGjYxBtH|#hCdAzBXl#fAhBtAtBjBhCfArAdAhAvBtBlB|AjGfFhLzJfEzDzCvDz#pA`BpC`ApBbAzBxCrIr#rBjNta#x#nBbAlBzCbI|R|j#hA`FBVC`ASpD?lA[FiMpCaBVgABiAPoE~#cIdBiLfCcHdBsCl#yJvBmDt#y#l#{#X_#P[VGJGZCd#r#tCf#rBTbAV`BB`#?n#GdA#XHj#bAxBl#hBPjADf#?v#Ej#Ml#Ut#[r#]h#sA`C{#lAMZGl#KjECbDGhBuGMsJKcCGw#CqJCiECAd#ALoBbKs#jDM^x#j#vPfLvCnB~DnCx#f#R#RAd#GDIbBmDv#y#LId#On#A~EJX#pDJrADb#QFC
Now you will add the polyline in the set of polylines like this
_polyLines.add(Polyline(
polylineId: PolylineId(Constants.currentRoutePolylineId),//pass any string here
width: 3,
geodesic: true,
points: Utils.convertToLatLng(Utils.decodePoly(encodedPoly)),
color: ConstantColors.PrimaryColor));
here encodedPoly is the same string that extracted from previous method.
In the function above you have to convert the points\encodedPoly into the list of latlng. Like i did using utils function.
Both functions that i used are
decodePoly :
// !DECODE POLY
static List decodePoly(String poly) {
var list = poly.codeUnits;
var lList = new List();
int index = 0;
int len = poly.length;
int c = 0;
// repeating until all attributes are decoded
do {
var shift = 0;
int result = 0;
// for decoding value of one attribute
do {
c = list[index] - 63;
result |= (c & 0x1F) << (shift * 5);
index++;
shift++;
} while (c >= 32);
/* if value is negative then bitwise not the value */
if (result & 1 == 1) {
result = ~result;
}
var result1 = (result >> 1) * 0.00001;
lList.add(result1);
} while (index < len);
/*adding to previous value as done in encoding */
for (var i = 2; i < lList.length; i++) lList[i] += lList[i - 2];
print(lList.toString());
return lList;
}
and convertToLatLng() :
static List<LatLng> convertToLatLng(List points) {
List<LatLng> result = <LatLng>[];
for (int i = 0; i < points.length; i++) {
if (i % 2 != 0) {
result.add(LatLng(points[i - 1], points[i]));
}
}
return result;
}
This would make a exact route like i did in my app :
Here is the screenshot :

Export html to Excel format? [duplicate]

I want to extract some data like " email addresses " .. from table which are in PDF file and use this email addresses which I extract to send email to those people.
What I have found so far through searching the web:
I have to convert the PDF file to Excel to read the data easily and use them as I want.
I find some free dll like itextsharp or PDFsharp.
But I didn't find any snippet code help to do this in C#. is there any solution ?
You absolutely do not have to convert PDF to Excel.
First of all, please determine whether your PDF contains textual data, or it is scanned image.
If it contains textual data, then you are right about using "some free dll". I recommend iTextSharp as it is popular and easy to use.
Now the controversial part. If you don't need rock solid solution, it would be easiest to read all PDF to a string and then retrieve emails using regular expression.
Here is example (not perfect) of reading PDF with iTextSharp and extracting emails:
public string PdfToString(string fileName)
{
var sb = new StringBuilder();
var reader = new PdfReader(fileName);
for (int page = 1; page <= reader.NumberOfPages; page++)
{
var strategy = new SimpleTextExtractionStrategy();
string text = PdfTextExtractor.GetTextFromPage(reader, page, strategy);
text = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(text)));
sb.Append(text);
}
reader.Close();
return sb.ToString();
}
//adjust expression as needed
Regex emailRegex = new Regex("Email Address (?<email>.+?) Passport No");
public IEnumerable<string> ExtractEmails(string content)
{
var matches = emailRegex.Matches(content);
foreach (Match m in matches)
{
yield return m.Groups["email"].Value;
}
}
Using bytescout PDF Extractor SDK we can be able to extract the whole page to csv as below.
CSVExtractor extractor = new CSVExtractor();
extractor.RegistrationName = "demo";
extractor.RegistrationKey = "demo";
TableDetector tdetector = new TableDetector();
tdetector.RegistrationKey = "demo";
tdetector.RegistrationName = "demo";
// Load the document
extractor.LoadDocumentFromFile("C:\\sample.pdf");
tdetector.LoadDocumentFromFile("C:\\sample.pdf");
int pageCount = tdetector.GetPageCount();
for (int i = 1; i <= pageCount; i++)
{
int j = 1;
do
{
extractor.SetExtractionArea(tdetector.GetPageRect_Left(i),
tdetector.GetPageRect_Top(i),
tdetector.GetPageRect_Width(i),
tdetector.GetPageRect_Height(i)
);
// and finally save the table into CSV file
extractor.SavePageCSVToFile(i, "C:\\page-" + i + "-table-" + j + ".csv");
j++;
} while (tdetector.FindNextTable()); // search next table
}
public void Convert(string fileNames) {
int pageCount = 0;
iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(fileNames);
pageCount = reader.NumberOfPages;
string ext = System.IO.Path.GetExtension(fileNames);
//string[] outfiles = new string[pageCount];
//Excel.Application app = new Excel.Application();
//app.Workbooks.Add("");
CSVExtractor extractor = new CSVExtractor();
//string outfilePDF1 = fileNames.Replace((System.IO.Path.GetFileName(fileNames)), (System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_rez" + ".csv"));
string outfilePDFExcel1 = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
(System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_rez" + ".xls"));
extractor.RegistrationName = "demo";
extractor.RegistrationKey = "demo";
string folderName = #"C:\Users\Dafina\Desktop\PDF_EditProject\PDF_EditProject\PDFs";
string pathString = System.IO.Path.Combine(folderName, System.IO.Path.GetFileName(fileNames).Replace(".pdf", "")) + "-CSVs";
System.IO.Directory.CreateDirectory(pathString);
for (int i = 0; i < pageCount; i++)
{
string outfilePDF = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
(System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_" + (i + 1).ToString()) + ext);
extractor.LoadDocumentFromFile(outfilePDF);
//string outfile = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
// (System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "_" + (i + 1).ToString()) + ".csv");
string outfile = fileNames.Replace((System.IO.Path.GetFileName(fileNames)),
(System.IO.Path.GetFileName(fileNames).Replace(".pdf", "") + "-CSVs\\" + "Sheet_" + (i + 1).ToString()) + ".csv");
extractor.SaveCSVToFile(outfile);
}
Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
if (xlApp == null)
{
Console.WriteLine("Excel is not properly installed!!");
return;
}
Excel.Workbook xlWorkBook;
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
string[] cvsFiles = Directory.GetFiles(pathString);
Array.Sort(cvsFiles, new AlphanumComparatorFast());
//string[] lista = new string[pageCount];
//for (int t = 0; t < pageCount; t++)
//{
// lista[t] = cvsFiles[t];
//}
//Array.Sort(lista, new AlphanumComparatorFast());
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
for (int i = 0; i < cvsFiles.Length; i++)
{
int sheet = i + 1;
xlWorkSheet = xlWorkBook.Sheets[sheet];
if (i < cvsFiles.Length - 1)
{
xlWorkBook.Worksheets.Add(Type.Missing, xlWorkSheet, Type.Missing, Type.Missing);
}
int sheetRow = 1;
Encoding objEncoding = Encoding.Default;
StreamReader readerd = new StreamReader(File.OpenRead(cvsFiles[i]));
int ColumLength = 0;
while (!readerd.EndOfStream)
{
string line = readerd.ReadLine();
Console.WriteLine(line);
try
{
string[] columns = line.Split((new char[] { '\"' }));
for (int col = 0; col < columns.Length; col++)
{
if (ColumLength < columns.Length)
{
ColumLength = columns.Length;
}
if (col % 2 == 0)
{
}
else if (columns[col] == "")
{
}
else
{
xlWorkSheet.Cells[sheetRow, col + 1] = columns[col].Replace("\"", "");
}
}
sheetRow++;
}
catch (Exception e)
{
string msg = e.Message;
}
}
int k = 1;
for (int s = 1; s <= ColumLength; s++)
{
xlWorkSheet.Columns[k].Delete();
k++;
}
releaseObject(xlWorkSheet);
readerd.Close();
}
xlWorkBook.SaveAs(outfilePDFExcel1, Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal,
misValue, misValue, misValue, misValue, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive,
misValue, misValue, misValue, misValue, misValue);
xlWorkBook.Close(true, misValue, misValue);
xlApp.Quit();
releaseObject(xlWorkBook);
releaseObject(xlApp);
var dir = new DirectoryInfo(pathString);
dir.Attributes = dir.Attributes & ~FileAttributes.ReadOnly;
dir.Delete(true);
}
Probably the Best code would be to use Third party dll
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
string pathToPdf = #"D:\abc\abc.pdf";
string pathToExcel = Path.ChangeExtension(pathToPdf, ".xls");
SautinSoft.PdfFocus f = new SautinSoft.PdfFocus();
f.ExcelOptions.ConvertNonTabularDataToSpreadsheet = false;
// 'true' = Preserve original page layout.
// 'false' = Place tables before text.
f.ExcelOptions.PreservePageLayout = true;
// The information includes the names for the culture, the writing system,
// the calendar used, the sort order of strings, and formatting for dates and numbers.
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-US");
ci.NumberFormat.NumberDecimalSeparator = ",";
ci.NumberFormat.NumberGroupSeparator = ".";
f.ExcelOptions.CultureInfo = ci;
f.OpenPdf(pathToPdf);
if (f.PageCount > 0)
{
int result = f.ToExcel(pathToExcel);
// Open the resulted Excel workbook.
if (result == 0)
{
System.Diagnostics.Process.Start(pathToExcel);
}
}
}
}
}

How to read a float in a csv with CAPL?

I have a .csv file and I want to read the data in its format, not at string.
This is the function that save the file in a readbuffer if is ok.
fileGetString(readbuffer,elcount(readbuffer),readHandle)!=0)
And I have the data is in this format:
Temperature;12.25;15.65;-25.12;80;
Time;1;2;4;7;
I want save the temperature in a buffer "Temperature[i]"
and do the same with the time "Time[i]"
How can I do this in CAPL?
I know that I can read each data like String and cast to integer or float doing some operations, but I want optimize code and read each data in its format.
You can convert an string to an float number using strtod().
Just for fun, here is complete example:
on start
{
dword fh;
char text[255];
double Temperature[4], Time[4];
int i;
/* open file */
fh = openFileRead("a.csv",0);
if (!fh) {
write ("ERROR: Open file failed!");
return;
}
/* read the 'Temperature' line */
if (!fileGetString(text, elcount(text), fh) ||
strstr(text, "Temperature;") != 0) {
write("ERROR: Wrong file format, 'Temperature' not found!");
return;
}
/* get the 'Temperature' values */
getValuesFromCsvString(text, Temperature);
/* read the 'Time' line */
if (!fileGetString(text, elcount(text), fh) ||
strstr(text, "Time;") != 0) {
write("ERROR: Wrong file format, 'Time' not found!");
return;
}
/* get the 'Time' values */
getValuesFromCsvString(text, Time);
/* output values */
for (i = 0; i < elcount(Temperature); i++)
write("Temperature[%i] = %6.2f", i, Temperature[i]);
for (i = 0; i < elcount(Time); i++)
write("Time[%i] = %2.0f", i, Time[i]);
}
int getValuesFromCsvString(char text[], double vals[])
{
long i, pos;
double res;
pos = strstr(text, ";");
str_replace(text, ";", " ");
for (i = 0; i < elcount(vals) ; i++) {
pos = strtod(text, pos, res);
if (pos >= 0)
vals[i] = res;
else
break;
}
return 0;
}
Output:
Temperature[0] = 12.25
Temperature[1] = 15.65
Temperature[2] = -25.12
Temperature[3] = 80.00
Time[0] = 1
Time[1] = 2
Time[2] = 4
Time[3] = 7