Arduino opening SD filename as string - c++

I am trying to open up a file that I calculate the name into a string. However, it is just giving me compile errors as shown.
for(int i=1;;i++)
{
String temp = "data";
temp.concat(i);
temp.concat(".csv");
if(!SD.exists(temp))//no matching function for call to sdclass::exists(String&)
{
datur = SD.open(temp,FILE_WRITE);
}
}
I am a java person, so I don't see why this isn't working. I tried a few string object methods but none seem to have worked. I am a bit new at arduino programming but I understand java much better. The point of this for loop is to make a new file each time the arduino reboots.

SD.open expects a character array instead of a String, you need to convert it using the toCharArray method first. Try
char filename[temp.length()+1];
temp.toCharArray(filename, sizeof(filename));
if(!SD.exists(filename)) {
...
}
Completed Code:
for(int i=1;;i++)
{
String temp = "data";
temp.concat(i);
temp.concat(".csv");
char filename[temp.length()+1];
temp.toCharArray(filename, sizeof(filename));
if(!SD.exists(filename))
{
datur = SD.open(filename,FILE_WRITE);
break;
}
}
You will find a number of functions take char arrays instead of strings.

Related

C Builder (C++) AnsiString Length method

I am used to program in c#, but now i had to help my roommate with a c++ project.
This is the "not working code" :
void HighlightKeyWords::Highlight(TRichEdit eMemo,TRichEdit RichEdit1)
{
ifstream file("KeyWords.txt");
AnsiString temp;
int maxWordLength=0;
if(file.is_open())
{
while(file>>temp)
{ if(temp.Length()> maxWordLength)
{
maxWordLength=temp.Trim().Length();
}
keyWords.push_back(temp);
}
file.close();
}
else
{
ShowMessage("Unable to open file. ");
}
for(unsigned i=0;i<KeyWords.size();i++)
{
richEdit1->Text=KeyWords[i];
}
eMemo->Text=MaxWordLength;
}
I get a list of keywords from the file. In MaxWordLength i want to know to maximum length of a word ( words are separated by new line in the text file ). When I do the temp.Length, i get 695 ( the number of all characters in the file ). Why am I not getting the actual length of the word i am adding to the vector?
Thank you!
LE: I also did the MaxWordLength logic in the for below, the for where i put the items in the RichEdit.
Use file.getline() instead of the >> operator, which won't produce the desired output in your case, but gives you the full file content as result. So AnsiString().Length() is not your problem. Just modify part of your code to get it working as intended:
char buffer[255];
if(file.is_open()){
while(file.getline(buffer, sizeof(buffer))){
temp = AnsiString(buffer).Trim();
if(temp.Length()> maxWordLength) maxWordLength=temp.Length();
keyWords.push_back(temp);
}
file.close();
}

C++, Trouble with string and int conversion

I know how to convert the string when it's just made up of integers, or it begins with ints. I am trying to convert to an integer when the string starts with a char in the beginning, or middle. I've tried running through a for loop, checking if (isdigit(str[i]) before trying stoi, stringstream, atoi, etc... None of them really work. I have the same problem even without the for loop. I've tried Googling my problem, but no luck. Any suggestions, or anything that I can try?
You have to check character by character if it's a digit or not and, if it is, add it to a new string. In the end, you convert your new string to an int like you would normally. Look at the code below. Hope I could help!
string s = "pc2jjj10";
char temp;
string result;
for (int i = 0; i < s.length(); i++){
temp = s.at(i);
if (isdigit(temp)){
result.push_back(temp);
}
}
int number = stoi(result);

Decode a message without a key

Here is what I should do
making a program that reads a text file that contains encrypted message and crack it it is kind of close to substitution cipher where I should swap swap each letter back with another meaning like shifting B back to A if its being shifted by one, and try comparing shifted words by some common used words to find if 2 of the common words have been found on the shifted ones
ex: shift the word by one
check when you shifted it is there 2 common words found?
no keep going
yes means thats it stop shifting
Now this issue here which makes the program hard for me is that I do not have a key to be entered it would've been awesome if I had it.
3 issues I am having now, is in my void function it will not print anything,
the second issue is, even if I fix my issue (I know this because in my function I have added something to convert string to c_string) and the issue is it will not shift until it finds the words I am looking which I have declared in string "Common[]"
3rd issue is whenever I compile I get an error invalid conversion from const char** to char comparison between signed and unsigned integer expressions
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <ctype.h>
using namespace std;
void makeshift (string encrypt, int key)
{
for (int i = 0 ; i<encrypt.size();i++)
{
cout<<encrypt<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt.c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
}
}
int main (int argc, char* argv[])
{
// this will make me compare between encrypted message to check if it
// contains this words or not!
const char* common[]{"the","and","in","he","with","that","as","at","do"};
string encrypted; // The encrypted message gotten from file
ifstream message(argv[1]); // get file name typed by user
if(message.is_open()) // check if file is open
{
while (!message.eof()) // check if we reached end of file
{
// get the whole line in file
getline(message,encrypted);
///loop throgh it to store numbers in declared varibles
for (int i = 0 ; i < encrypted.size();i++)
{
makeshift(encrypted,i);
// here is where the error occurs which is "invalid conversion
// from const char to char
if(encrypted.find(common) != -1)
{
cout<<"found common"<<endl;
cout<<encrypted<<endl;
break;
}
}
}
}
}
Compile error
First, you say you're getting a compile error on this line:
if(encrypted.find(common) != -1)
The reason for that is because find() expects its argument to be a string, but common is an array of strings. In other words, find() can only search for one word at a time. It can't search for a whole list of words.
To fix that, you'll want to write a loop and check one word each iteration.
Shift function
Next up is the makeshift function. A couple of suggestions there.
There's no real need to call c_str(). You can change encrypted directly by modifying each encrypted[i] in the loop.
It needs to return the result. If you modify encrypted but do not return it then the caller won't see the result.
The printouts ought to be outside the loop. Presumably you just want to see the before and after results after you've decrypted the entire string.
Here's what it looks like with those issues addressed:
string makeshift (string encrypt, int key)
{
cout << encrypt << endl; // to see what is in file way to debug
for (int i = 0 ; i<encrypt.size();i++)
{
encrypted[i] -= key;
}
cout << "decrypted message is " << encryptedc << endl;
return encrypted;
}
And then you would call it as:
string decrypted = makeshift(encrypted, i);
By the way, I'm not sure if the encrypted[i] -= key; line is completely correct. My guess is you'll need to handle wraparound. Like if you subtract 3 from the letter "A" you should probably wrap around to "X", correct? If so, I'll leave that as a TODO for you.
I/O error checking
Lastly, let's talk about I/O. Specifically, this bit of code:
ifstream message(argv[1]); // get file name typed by user
if(message.is_open()) // check if file is open
{
while (!message.eof()) // check if we reached end of file
{
// get the whole line in file
getline(message,encrypted);
...
}
}
A good practice in C++ is to check the results of I/O operations (e.g. getline). After you read a line you need to check that the read actually worked. You don't want to continue on if getline() failed (say, because it hit end-of-file).
Conveniently, if you write while (getline(...)) then that'll do a whole bunch of things all at once--it'll check if the file is open, if it's at EOF, and it'll read lines and tell you if the reads were successful. That means you can replace the stuff above with a single loop:
ifstream message(argv[1]); // get file name typed by user
while (getline(message, encrypted))
{
...
}
You are passing the value of encrypted to makeshift, so whatever you do in makeshift function will not change the encrypted in main function
you have 2 solutions here:
you can either pass the pointer of encrypted to the makeshift function
void makeshift (string* encrypt, int key){
for (int i = 0 ; i<encrypt.size();i++)
{ cout<<encrypt->c_str()<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt->c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
}
}
int main (int argc, char* argv[]){
...
makeshift(&encrypted, i);
...
}
Or you can return the value of encryptedc and assign it back to encrypted in main function
string makeshift (string encrypt, int key){
for (int i = 0 ; i<encrypt.size();i++)
{ cout<<encrypt.c_str()<<endl; // to see what is in file way to debug
const char *encryptedc; // this is to convert string to cstring
encryptedc = encrypt.c_str();
encryptedc-=key;
cout<<"decrypted message is "<<encryptedc<<endl;
return encryptedc; //you can assign const char* to string
}
}
int main (int argc, char* argv[]){
...
encrypted = makeshift(encrypted, i);
...
}

weird behaviour of strstr in qt program

I'm a beginner, made a function which takes input from lineedit converts it into a array and then searches it to find a word. If the word is found it prints successs in a label, otherwise prints error.Problem is that it every time prints error no matter what i enter.
What am I doing wrong.
void MainWindow::on_consoleEdit_returnPressed()
{
QString text = ui->consoleEdit->text();
char enteredCmd[4096];
strcpy(enteredCmd, "Some string data");
text = enteredCmd;
//enteredCmd contains all the data that text string contains
char *open = strstr(enteredCmd, "open");
if(open != NULL) {
ui->answerLabel->setText("SUCCESS");
}
else {
ui->answerLabel->setText("ERROR");
}
}
You are testing same string every time, see this:
char enteredCmd[4096];
strcpy(enteredCmd, "Some string data");
text = enteredCmd;
this overrides text value with copy of this "Some string data" string.
Anyway you made this to complicated. QString have lots of functionality useful for you.
void MainWindow::on_consoleEdit_returnPressed()
{
QString text = ui->consoleEdit->text();
if(text.contains("open")) {
ui->answerLabel->setText("SUCCESS");
} else {
ui->answerLabel->setText("ERROR");
}
}
Your code is not searching on the text from the line edit. Your code is actually searching for "open" on the string enteredCmd, which always contains "Some string data". Thus, you should always get "ERROR" printed to your answer label.
Here's what I think you are trying to do, using QString instead of strstr:
void MainWindow::on_consoleEdit_returnPressed()
{
QString text = ui->consoleEdit->text();
if(text.contains(QStringLiteral("open"))) {
ui->answerLabel->setText("SUCCESS");
}
else {
ui->answerLabel->setText("ERROR");
}
}
QString is designed to work with many languages so it requires some conversion to get text to a C style eight bit string. You might try something like this:
char *myChar = text.toLatin1().data();

Adding char to string in C++

I work with Eclipse and Arduino.
I want to add a char to a string. I tried to use append,insert ( but these can not be resolved)
I tried to use += but when i print the string it always have one char.Basically i deletes the string and writes only the new char i want to add in.
I tried also concat and it does the same thing.Also strcat gives me headache with the operands cause it needs a const char pointer and i want to add a char that changes.
while (theSettings.available()) {
character = theSettings.read();
if(character == '/') {
// Comment - ignore this line
while(character != '\n'){
character = theSettings.read();
}
} else if(isalnum(character)){ // Add a character to the description
Serial.println(character);
description +=character;
//description.concat(character);
Serial.println(description);
}
It sounds like what you want (for convenience) is the String object class available with the Arduino library.
http://arduino.cc/en/Reference/StringObject
If description is of the Ardunio-specific String type, you should be able to use the += operator to append.
You can do a very simple thing;
Serial.print(character);
Serial.print("");
Serial.println(description);
alternatively you can use "dtostrf" if you need to concatenate float and strings