Writing to a file using echo - c++

void EDataset::PrintErr(const NDataString& ErrMsg){
system("echo " + $ErrMsg + " >> err.txt");
.... code ....
}
It prints blank line as the value of ErrMsg. How come?

As already #gf mentioned in the comment, $ErrMsg is not proper. Also, NDataString definition is not clear.
Assuming there is a way to get string out of NDataString :
void PrintErr(const NDataString& ErrMsg)
{
std::stringstream tempString;
tempString <<"echo ";
//Get the string out of NDataString...
//if ErrMsg was std::string then c_str() will give you const char*
tempString<< ErrMsg.c_str();
tempString<<" >> err.txt";
system(tempString.c_str());
}

Related

get-line gets always the same line C++

I have a file with data like this
10000 9.425 1.00216 -0.149976
20000 19.425 0.973893 -0.135456
30000 29.425 1.01707 -0.115423
40000 39.425 1.0181 -0.12074
.
.
.
to get the data what I am doing is to read the whole line and then separate the line by the spaces to get the data I need. The problem is that the file has 3000 lines so I tried to get the line in a for loop
std::vector<std::string> a;
std::ifstream datas("Data/thermo_stability.dat");
std::string str;
char d=' ';
for(int i=0; i<n; i++)
{
std::getline(datas, str);
tokenize(str,d,a);
x[i]=std::atof((a[1]).c_str());
y[i]=std::atof((a[3]).c_str());
std::cout << x[i] << "\t" << y[i] << std::endl;
}
I noticed that something was wrong so I added that cout and found out that it was always getting the same line. How can I fix this problem? Why is not getting the next line after getline is called? When I do it outside the loop it goes to the next line.
EDIT
here is the tokenized function
void tokenize(std::string &str, char delim, std::vector<std::string> &out)
{
size_t start;
size_t end = 0;
while ((start = str.find_first_not_of(delim, end)) != std::string::npos)
{
end = str.find(delim, start);
out.push_back(str.substr(start, end - start));
}
}
Have some issues with that code:
I don't see where n is set so how do you know it is correct. The proper way to read a line is to call getline() and then test it worked (it can be done in a single line).
while(std::getline(datas, str)) {
// Successfully read a line from the file
}
You don't need to manually convert string to integers or floats. The stream library will do that automatically.
std::istringstream lineStream(std::move(str));
str.clear();
int value1; // please use better names:
double value2;
double value3;
double value4;
lineStream >> value1 >> value2 >> value3 >> value4;

How can I add a zero at the end of a string?

I'm trying to read some text out of a file called "file.dat". The problem is, that the string in the file does not include a zero at the end as for standard C. So I need something that adds the zero, so I can work with the string without getting random symbols after the string when I print it.
void cSpectrum::readSpectrum(const std::string &filename, double
tubeVoltage, double &minEnergy, std::string &spectrumName)
{
//Object with the name "inp" of the class ifstream
ifstream inp(filename, ios::binary);
//Checks if the file is open
if (!inp.is_open()) {
throw runtime_error("File not open!");
}
cout << "I opened the file!" << endl;
//Check the title of the file
string title;
char *buffer = new char[14];
inp.read(buffer, 14);
cout << buffer << endl;
}
At the moment I get the following output, I would like to get it without the ²²²²┘.
I opened the file!
x-ray spectrum²²²²┘
Simply allocate +1 more char for your array, but don't read into that char, just set it to 0:
char buffer[15];
inp.read(buffer, 14);
buffer[14] = '\0';
cout << buffer << endl;
Or, simply don't use a char[] at all, use std::string instead, see:
What is the best way to read an entire file into a std::string in C++?
I did it with the std::string now. If you want you can replace the 14 by an integer variable.
void cSpectrum::readSpectrum(const std::string & filename, double tubeVoltage, double
& minEnergy, std::string const & spectrumName){
ifstream inp(filename, ios::binary);
//Checks if the file is open
if (!inp.is_open()) {
throw runtime_error("ERROR: Could not open the file!");
}
//Reads the title
string title(14, '\0');
inp.read(&title[0], 14);
//If it is not the correct file throw an ERROR
if (title != spectrumName)
throw runtime_error("ERROR: Wrong file title");
readSpectrum(inp, tubeVoltage, minEnergy, spectrumName);
}

Exception Handling Between Functions c++

I'm taking a basic OOP in C++ class. One of our assignments is to read lines from a file, run them through a function (parseLine()) that converts a string to a string stream, throw exceptions from that parseLine, catch the exceptions in the readFile function and write the lines that threw exceptions to the console. The lines that did not throw exceptions should be added to a struct array.
The problem: The throws are not being thrown, or not being caught.
I have spent hours playing with the formatting trying to figure out why my try catch statement isn't working. I wish I could ask a more specific question, but I believe the answer will be obvious to a more experienced programmer who sees my code
Note: Formatting style is prescribed by the class.
/**********************************************************************
* struct: Record
* fileName
* user
* time
***********************************************************************/
struct Record
{
string file;
string user;
long time;
};
/**********************************************************************
* function: parseLine
* parse line into struct
***********************************************************************/
void parseLine(const string & line, Record & buffer) throw (string)
{
assert(line.length() > 0);
stringstream ss;
ss.str(line);
// stream string to struct
ss >> buffer.file;
if (ss.fail())
{
ss.clear();
throw string(line);
}
ss >> buffer.user;
if (ss.fail())
{
ss.clear();
throw string(line);
}
ss >> buffer.time;
if (ss.fail() || buffer.time < 1,000,000,000 || buffer.time > 10,000,000,000)
{
ss.clear();
throw string(line);
}
}
/**********************************************************************
* function: readFile
* read from the file name provided by the user
***********************************************************************/
int readFile(const string & fileName, Record record[])
{
// declare fstream variable
ifstream fin(fileName.c_str());
// error check
if (fin.fail())
{
cout << "ERROR: Unable to read file "
<< fileName
<< endl;
return 0;
}
// loop through file and store it
Record buffer;
string line;
int size = 0;
while (getline(fin, line) && size < 500)
{
try
{
parseLine(line, buffer);
record[size] = buffer;
}
catch (string text)
{
cout << "Error parsing line: "
<< text
<< endl;
}
size++;
}
// close the file
fin.close();
return size;
}
Question 1 The file being read purposely contains errors (Empty lines, ints in unexpected places, etc), it seems like the ss.fail() is not being triggered, how could that happen?
Question 2 Is my try/catch block written correctly?
Thank you very much for your help!
Your integer literals should not contain commas.
The comma is actually a C++ operator.

Replace words in a string without skipping whitespaces

I've got a string which contains a sentence. I have to search and replace a specific word in that string. In my case I have a vector of lines and another vector of words to replace.
Here's my function that generates a file with the final text:
void Generator::generate_file(const string& fileName){
string inBuffer, outBuffer;
std::stringstream ss;
std::ofstream outFile;
outFile.open(fileName);
for (const auto& inIT : userCode){
//userCode is a vector which contains lines of text
ss.str(inIT);
ss.clear();
outBuffer = "";
while (ss >> inBuffer){
for (auto keyIT : keywords){
//keywords is a vector which contains words to replace
if (keyIT == inBuffer)
inBuffer = "REPLACED";
}
outBuffer += inBuffer + " ";
}
outFile << outBuffer << endl;
}
outFile.close();
}
The problem with this function is that it skips all whitespaces. I need them in the output file. What should I do to achieve that?
Below you can see an example of how it works:
userCode:
userCode[0] = "class UrlEncoder(object): class";
userCode[1] = " def __init__(self, alphabet=DEFAULT_ALPHABET,\n block_size=DEFAULT_BLOCK_SIZE):";
Displaying the userCode vector:
class UrlEncoder(object):
def __init__(self, alphabet=DEFAULT_ALPHABET, block_size=DEFAULT_BLOCK_SIZE):
After executing my function it looks like this:
REPLACED UrlEncoder(object):
REPLACED __init__(self, alphabet=DEFAULT_ALPHABET, block_size=DEFAULT_BLOCK_SIZE):
As you can see it properly replaced the keywords. But unfortunately it skipped the tabulator.
The main issue is the way the stream extraction >> operator works. It removes and discards any leading whitespace characters when reading the next formatted input. Assuming you want to stick with using ss >> inBuffer when grabbing input, you need to find someway to preemptively grab any leading whitespace before you perform any input extraction.
For example,
string eatwhite(const string &str, size_t pos)
{
size_t endwhite = str.find_first_not_of(" \t\n", pos);
if (endwhite == string::npos) return "";
return string(str.begin() + pos, str.begin() + endwhite);
}
Now you would call eatwhite before doing any >>:
string outBuffer = eatwhite(ss.str(), ss.tellg());
while (ss >> inBuffer)
{
for (auto keyIT : keywords)
{
//...
}
string whitesp = eatwhite(ss.str(), ss.tellg());
outBuffer += inBuffer + whitesp;
}
outFile << outBuffer << endl;

getline() method no instance of overloaded function

I am having some problem when trying to do classes for C++. This is my header file.h:
#include <iostream>
#include <string>
#ifndef MESSAGES__H__
#define MESSAGES__H__
class Message
{
public:
Message(std::string recipient, std::string sender);
void append(std::string text);
std::string to_string() const;
void print() const;
private:
std::string recipient;
std::string sender;
std::string message;
std::string text_input;
char* timestamp;
};
#endif
And when I run the main method, the getline(cin,) is giving me some error message:
int main()
{
vector <Message*> message_list;
Message* message1 = new Message("Student1", "Gabriel");
cout << "Enter message text line, enter . on new line to finish: " << endl;
while(getline(cin, text_input))
{
}
}
The getline method is giving me no instance of overloaded function. Also, from the same line, the text_input is showing identifier is undefined. I thought I declared in .h class already?
Thanks in advance.
Updated portion
Now all the error has been fixed:
vector <Message*> message_list;
Message* message1 = new Message("Saiful", "Gabriel");
cout << "Enter message text line, enter . on new line to finish: " << endl;
while(getline(cin, message1->get_text_input()))
{
if(message1->get_text_input() == ("."))
{
break;
}
else
{
message1->append(message1->get_text_input());
}
}
Inside the while loop, once "." is detected at the beginning of the new line, it supposingly will stop. However, no matter how many times I entered "." at the new line, it just keep prompting. Anybody know why?
To fix "text_input is showing identifier is undefined"
You need to change
while(getline(cin, text_input))
to
while(getline(cin, message1->text_input))
Possibly this will fix the first error.
Try changing your loop like this:
while(getline(cin,&message1->text_input))
{
}
If I remember correctly, getline function looks like this:
getline(isstream& stream, string& string)
It feels as if you are over complicating things. Just use a temporary variable in getline. If the input is a "." then break, otherwise append the line to the Message object. As a consequence, you should be able to remove the text_input member variable from your Message header file.
std::vector<Message*> message_list;
Message* message1 = new Message("Saiful", "Gabriel");
std::cout << "Enter message text line, enter . on new line to finish: " << std::endl;
std::string input = "";
while(getline(std::cin, input))
{
if(input == ".")
{
break;
}
else
{
message1->append(input);
}
}