Adding char to string in C++ - 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

Related

How do I remove only the first character of a string that is not a digit? (MFC, C++)

I want to remove only the first character in a string that is NOT a digit. The first character can be anything from ‘A’ to ‘Z’ or it may be a special character like ‘&’ or ‘#’. This legacy code is written in MFC. I've looked at the CString class but cannot figure out how to make this work.
I have strings that may look like any of the following:
J22008943452GF or 22008943452GF or K33423333333IF or 23000526987IF or #12000895236GF. You get the idea by now.
My dilemma is I need to remove the character in the first position of all the strings, but not the strings that starts with a digit. For the strings that begin with a digit, I need to leave them alone. Also, none of the other characters in the string should not be altered. For example the ‘G’, ‘I’ or ‘F’ in the later part of the string should not be changed. The length of the string will always be 13 or 14 digits.
Here is what I have so far.
CString GAbsMeterCalibration::TrimMeterSNString (CString meterSN)
{
meterSN.MakeUpper();
CString TrimmedMeterSNString = meterSN;
int strlength = strlen(TrimmedMeterSNString);
if (strlength == 13)
{
// Check the first character anyway, even though it’s
// probably okay. If it is a digit, life’s good.
// Return unaltered TrimmedMeterSNString;
}
if (strlength == 14))
{
//Check the first character, it’s probably going
// to be wrong and is a character, not a digit.
// if I find a char in the first postion of the
// string, delete it and shift everything to the
// left. Make this my new TrimmedMeterSNString
// return altered TrimmedMeterSNString;
}
}
The string lengths are checked and validated before the calls.
From my investigations, I’ve found that MFC does not have a regular expression
class. Nor does it have the substring methods.
How about:
CString GAbsMeterCalibration::TrimMeterSNString (CString meterSN)
{
meterSN.MakeUpper();
CString TrimmedMeterSNString = meterSN;
int strlength = strlen(TrimmedMeterSNString);
if (std::isdigit(TrimmedMeterSNString.GetAt(0)) )
{
// Check the first character anyway, even though it’s
// probably okay. If it is a digit, life’s good.
// Return unaltered TrimmedMeterSNString;
}
}
From what I understand, you want to remove the first letter if it is not a digit. So you may make this function simpler:
CString GAbsMeterCalibration::TrimMeterSNString(CString meterSN)
{
meterSN.MakeUpper();
int length = meterSN.GetLength();
// just check the first character is always a digit else remove it
if (length > 0 && unsigned(meterSN[0] - TCHAR('0')) > unsigned('9'))
{
return meterSN.Right(length - 1);
}
return meterSN;
}
I am not using function isdigit instead of the conditional trick with unsigned because CString uses TCHAR which can be either char or wchar_t.
The solution is fairly straight forward:
CString GAbsMeterCalibration::TrimMeterSNString(CString meterSN) {
meterSN.MakeUpper();
return _istdigit(meterSN.GetAt(0)) ? meterSN :
meterSN.Mid(1);
}
The implementation can be compiled for both ANSI and Unicode project settings by using _istdigit. This is required since you are using CString, which stores either MBCS or Unicode character strings. The desired substring is extracted using CStringT::Mid.
(Note that CString is a typedef for a specific CStringT template instantiation, depending on your project settings.)
CString test="12355adaddfca";
if((test.GetAt(0)>=48)&&(test.GetAt(0)<=57))
{
//48 and 57 are ascii values of 0&9, hence this is a digit
//do your stuff
//CString::GetBuffer may help here??
}
else
{
//it is not a digit, do your stuff
}
Compare the ascii value of the first position in the string and you know if it's a digit or not..
I don't know if you've tried this, but, it should work.
CString str = _T("#12000895236GF");
// check string to see if it starts with digit.
CString result = str.SpanIncluding(_T("0123456789"));
// if result is empty, string does not start with a number
// and we can remove the first character. Otherwise, string
// remains intact.
if (result.IsEmpty())
str = str.Mid(1);
Seems a little easier than what's been proposed.

Pull out data from a file and store it in strings in C++

I have a file which contains records of students in the following format.
Umar|Ejaz|12345|umar#umar.com
Majid|Hussain|12345|majid#majid.com
Ali|Akbar|12345|ali#geeks-inn.com
Mahtab|Maqsood|12345|mahtab#myself.com
Juanid|Asghar|12345|junaid#junaid.com
The data has been stored according to the following format:
firstName|lastName|contactNumber|email
The total number of lines(records) can not exceed the limit 100. In my program, I've defined the following string variables.
#define MAX_SIZE 100
// other code
string firstName[MAX_SIZE];
string lastName[MAX_SIZE];
string contactNumber[MAX_SIZE];
string email[MAX_SIZE];
Now, I want to pull data from the file, and using the delimiter '|', I want to put data in the corresponding strings. I'm using the following strategy to put back data into string variables.
ifstream readFromFile;
readFromFile.open("output.txt");
// other code
int x = 0;
string temp;
while(getline(readFromFile, temp)) {
int charPosition = 0;
while(temp[charPosition] != '|') {
firstName[x] += temp[charPosition];
charPosition++;
}
while(temp[charPosition] != '|') {
lastName[x] += temp[charPosition];
charPosition++;
}
while(temp[charPosition] != '|') {
contactNumber[x] += temp[charPosition];
charPosition++;
}
while(temp[charPosition] != endl) {
email[x] += temp[charPosition];
charPosition++;
}
x++;
}
Is it necessary to attach null character '\0' at the end of each string? And if I do not attach, will it create problems when I will be actually implementing those string variables in my program. I'm a new to C++, and I've come up with this solution. If anybody has better technique, he is surely welcome.
Edit: Also I can't compare a char(acter) with endl, how can I?
Edit: The code that I've written isn't working. It gives me following error.
Segmentation fault (core dumped)
Note: I can only use .txt file. A .csv file can't be used.
There are many techniques to do this. I suggest searching StackOveflow for "[C++] read file" to see some more methods.
Find and Substring
You could use the std::string::find method to find the delimiter and then use std::string::substr to return a substring between the position and the delimiter.
std::string::size_type position = 0;
positition = temp.find('|');
if (position != std::string::npos)
{
firstName[x] = temp.substr(0, position);
}
If you don't terminate a a C-style string with a null character there is no way to determine where the string ends. Thus, you'll need to terminate the strings.
I would personally read the data into std::string objects:
std::string first, last, etc;
while (std::getline(readFromFile, first, '|')
&& std::getline(readFromFile, last, '|')
&& std::getline(readFromFile, etc)) {
// do something with the input
}
std::endl is a manipulator implemented as a function template. You can't compare a char with that. There is also hardly ever a reason to use std::endl because it flushes the stream after adding a newline which makes writing really slow. You probably meant to compare to a newline character, i.e., to '\n'. However, since you read the string with std::getline() the line break character will already be removed! You need to make sure you don't access more than temp.size() characters otherwise.
Your record also contains arrays of strings rather than arrays of characters and you assign individual chars to them. You either wanted to yse char something[SIZE] or you'd store strings!

How do I return the end of a directory

I have a function that is supposed to find the last bit of a directory in a string. eg:
"C:\Lolcats\pie\ambulance\" should return "ambulance". However it returns some strange characters ive never seen, like the male arrow-point symbol and some other weird stuff.
string App::getlastName(string cakes){
//finds the name of the last folder in a directory
string name;
string temp;//popback all of temp into name to invert it
cakes.pop_back();
char i = cakes[cakes.length()-1];
while (i != '\\'){
temp.push_back(cakes[i]);
cakes.pop_back();
i = cakes[cakes.length()-1];
} //-1?
for (int j = 0; j<temp.length(); ++j){
name.push_back(temp.back());
temp.pop_back();
}
return name;
}
This is probably one of the worst functions i've ever written, but I can't think of how else to wrangle the end off :( Can someone help me please? :D
Note that the function doesnt need to find the name of a file, it'll just be folders.
Two steps:
if it ends with a backslash character remove it:
if (!cakes.empty() && '\\' == *(cakes.end() - 1))
{
cakes.erase(cakes.end() - 1);
}
use std::string::find_last_of() to locate last backslash and std::string::substr() to extract the last part:
std::string last_part;
const size_t slash_idx = cakes.find_last_of("\\");
if (std::string::npos != slash_idx)
{
last_part = cakes.substr(slash_idx + 1);
}
If it is possible that the directory name could contain forward slashes add the additional check for the last character and just add it to the argument to find_last_of("\\/"), as it can search for more than one character.
If you remove the trailing \ off the string you can use a simple combination of rfind and substr to get the data you want.
string substring = cakes.substr(cakes.rfind("\\") + 1);
#Joel Rondeau's comment where he says that the line temp.push_back(cakes[i]) is a problem is correct, but I thought I would elaborate.
The reason is that the variable i is defined as a char not an int, but it is possible for the two to be cast implicitly. So the reason why you are getting strange characters returned is because casting a char to an int has resulted in an index value that probably does not exist in your string.
Reading your code sample it looks like you should be doing temp.push_back(cakes[cakes.length()-1]) instead (or better, store this index in a temp variable so you don't have to keep writing it every time).
Your method depends on the string already being in the correct format with no assertions or error checking--not a good idea.
I would just do something like:
char* directoryName = strrchr(fullPath, '\\') + 1;
after you have trimmed off the trailing '\'.

testing for double in visual c++

I am designing a gui in visual c++ and there is a textbox where user inputs values so a calculation can be performed. How do I validate the input to ensure it can be cast to a double value?
In any C++ environment where you have a std::string field and wish to check if it contains a double, you can simply do something like:
#include <sstream>
std::istringstream iss(string_value);
double double_value;
char trailing_junk;
if (iss >> double_value && !(iss >> trailing_junk))
{
// can use the double...
}
As presented, this will reject things like "1.234q" or "-13 what?" but accept surrounding whitespace e.g. " 3.9E2 ". If you want to reject whitespace, try #include <iomanip> then if (iss >> std::noskipws >> double_value && iss.peek() == EOF) ....
You could also do this using old-style C APIs:
double double_value;
if (sscanf(string_value.c_str(), "%lf%*c", &double_value) == 1)
You cannot "cast" a string to a double, you can only convert it. strtod function will return a pointer to the character within the string where the conversion stopped, so you can decide what to do further. So you can use this function for conversion AND checking.
I'd recommend Boost's lexical_cast, which will throw an exception if the conversion fails.
Since this seems to be a C++ CLI related question and your string from the textbox might be a .NET string, you might want to check the static Double::Parse method. For more portable solutions see the other answers...
As stated already, strtod(3) is the answer.
bool is_double(const char* str) {
char *end = 0;
strtod(str, &end);
// Is the end point of the double the end of string?
return end == str + strlen(str);
}
To address #Ian Goldby's concern, if white space at the end of the sting is a concern, then:
bool is_double(const char* str) {
char *end = 0;
strtod(str, &end);
// Is the end point of the double plus white space the end of string?
return end + strspn(end, " \t\n\r") == str + strlen(str);
}
Simply convert it to a double value. If it succeeds, the input is valid.
Really, you shouldn't be writing your own rules for deciding what is valid. You'll never get exactly the same rules as the library function that will do the actual conversion.
My favourite recipe is to use sscanf(), and check the return value to ensure exactly one field was converted. For extra credit, use a %n parameter to check that no non-whitespace characters were left over.

Parsing a string by a delimeter in C++

Ok, so I need some info parsed and I would like to know what would be the best way to do it.
Ok so here is the string that I need to parse. The delimeter is the "^"
John Doe^Male^20
I need to parse the string into name, gender, and age variables. What would be the best way to do it in C++? I was thinking about looping and set the condition to while(!string.empty()
and then assign all characters up until the '^' to a string, and then erase what I have already assigned. Is there a better way of doing this?
You can use getline in C++ stream.
istream& getline(istream& is,string& str,char delimiter=’\n’)
change delimiter to '^'
You have a few options. One good option you have, if you can use boost, is the split algorithm they provide in their string library. You can check out this so question to see the boost answer in action: How to split a string in c
If you cannot use boost, you can use string::find to get the index of a character:
string str = "John Doe^Male^20";
int last = 0;
int cPos = -1;
while ((cPos = str.find('^', cPos + 1)) != string::npos)
{
string sub = str.substr(last, cPos - last);
// Do something with the string
last = cPos + 1;
}
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch;
printf ("Looking for the 's' character in \"%s\"...\n",str);
pch=strchr(str,'s');
while (pch!=NULL)
{
printf ("found at %d\n",pch-str+1);
pch=strchr(pch+1,'s');
}
return 0;
}
Do something like this in an array.
You have a number of choices but I would use strtok(), myself. It would make short work of this.