So I'm having some troubles with a segfault right now.
The problem appears to be on line 122
file_stream.read(binaryData, fileSizeInt);
The message seems to be unable to create variable object.
I'm using the debugger on CLion, if this is of any help.
I'm fairly new to C++ so please bear with me on this. I've included my source code below, since I have no idea what will and wont be relevant.
#include <fstream>
#include <iostream>
#include <math.h>
using namespace std;
//string dataLocation = "/dev/rdisk2"; // Variable for the mounting point of the SD Card.
string dataLocation = "/Volumes/Untitled/data/smith_data_backup.dat"; // Test location
int sectorSize = 512;
int bytesRead = 0;
string outDir = "/Volumes/Untitled/data/readData/";
char data_stop[10] = "Data_Stop";
char* findHeader(char* inputData) {
int i = 1;
//look for the end of the header
while(true) {
//cout << data[i] << '\n';
if (inputData[i] == '}') {
// found the end of the header
cout << "found the end of the header" << '\n';
break;
}
if (i > 200) { // don't get into an infinite loop here
cout << "something went wrong here" << '\n';
break;
}
i++;
}
// copy the header to a new char array
char* header = new char[i+1];
memcpy(header, &inputData[0], (size_t) (i +1));
return header;
}
int main() {
ifstream file_stream;
file_stream.open(dataLocation);
for( int j = 0; j < 10; j++ ) {
char data[sectorSize]; // figure out a decent size for this.....
string date = "";
string time = "";
string site = "";
string intId = "";
string totalFiles = "";
string fileNo = "";
string fileSize = "";
try {
// read the data file... this will be fun
cout << "Reading the data file" << '\n';
file_stream.read(data, sectorSize);
bytesRead += sectorSize;
if (data[0] == '{') {
char *header = findHeader(data);
cout << header << '\n';
//loop over the header to find the date, time, site ID, Instrument ID, and expected file size.
int commasFound = 0;
for(int i = 1; header[i] != '}', i++;) {
// increment the number of commas that have been found
if (header[i] == ',') {
commasFound ++;
continue;
}
//check for the end f the header
if (header[i] == '}') {
break;
}
//for some reason the first one never gets added
if (i==2) {
date += header[1];
}
// append to appropriate strings based on the number of commas that have been passed in the header
if (commasFound == 0) {
date += header[i];
}
if (commasFound == 1 && time.length() < 6) {
time += header[i];
}
if (commasFound == 2) {
fileNo += header[i];
}
if (commasFound == 6) {
site += header[i];
}
if (commasFound == 8) {
intId += header[i];
}
if (commasFound == 16) {
fileSize += header[i];
}
if (commasFound == 17) {
totalFiles += header[i];
}
//paranoia of infinite loops
if (i > 150) {
break;
}
}
string formattedDate = "20" + date.substr(4,2) + date.substr(2,2) + date.substr(0,2);
cout << formattedDate << " " << time << " " << " " << site << " " << intId << " " << fileSize << " " << totalFiles<< " " << '\n';
// Read in the data size
int fileSizeInt = atoi(fileSize.c_str()) * atoi(fileSize.c_str());
char binaryData[fileSizeInt];
file_stream.read(binaryData, fileSizeInt);
bytesRead += fileSizeInt;
string dateDir = outDir + formattedDate.substr(0,4) + "/" + date.substr(2,2) + "/" + site + "/" + date.substr(0,2) + "/";
string fileName = dateDir + formattedDate + "_" + time + "_" + site + "_" + intId + "_Full_Data.dat";
//cout << fileName << '\n';
//create the directory with the date.
string mkdirCommand = "mkdir -p " + dateDir;
system(mkdirCommand.c_str());
cout << "size " << sizeof(binaryData) << '\n';
//write data to file
try {
cout << "Write the data file " << '\n';
cout << header << " " << strlen(header) << '\n';
ofstream outFile;
outFile.open(fileName.c_str());
outFile.write(header, strlen(header));
outFile.write(binaryData, sizeof(binaryData));
outFile.write(data_stop, sizeof(data_stop));
outFile.close();
} catch (ofstream::failure e ) {
cout << "Unable to write the file " << fileName << '\n';
}
//read till the start of the next sector
int nextSector = (int) ceil(((double) bytesRead)/512.0);
int startOfNextSector = nextSector * 512;
cout << startOfNextSector << '\n';
int bytesToRead = startOfNextSector - bytesRead;
char dump[bytesToRead];
file_stream.read(dump, bytesToRead);
bytesRead += bytesToRead;
// The first block may be empty, quick check to see if the first block needs to be skipped
} else if (j == 0 && data[0] != '{') {
cout << "Skipping the first block" << '\n';
continue;
} else {
//cout << "no start here....." << bytesRead << '\n';
}
}
catch (ifstream::failure& e) {
cout << "Error" << "\n";
break;
}
}
file_stream.close();
return 0;
}
Related
I was unlucky enough that his exact code was actually working for me. There is obviously some underlying problem that I am not seeing/understanding because it no longer works.
This is what is happening:
I am streaming data from a file, and when using the
buffer >> table_data;
As I output table_data each time, it is starting from the middle of the buffer.
The tricky thing, If I output the buffer using
std::cout << buffer.str();
That yields the correct data. So the stream buffer, has all of the right things, its just not going into table_data correctly.
See full code block below.
//read from table
buffer << table.rdbuf();
buffer.clear();
//clear table contents for rewrite later
table.clear();
std::ofstream table(filename);
while (buffer >> table_data)
{
temp_vec.push_back(table_data);
//num_table_items = 3, which is correct.
for (int i = 1; i < num_table_items; i++)
{
buffer >> table_data;
temp_vec.push_back(table_data);
}
//I removed the part where I write to the table from the vector because the problem is above.
temp_vec.clear();
}
if it matters, this is what the buffer is reading from the file:
1 'Gizmo' 19.99
2 'PowerGizmo' 29.99
3 'SingleTouch' 149.99
4 'MultiTouch' 199.99
5 'SuperGizmo' 49.99
And thats what is printed when I do the std::cout << buffer.str();
however, if I print table data after both "buffer >> table_data" lines in the code, i get this (same results if I print the vector):
Gizmo' 29.99 3
'SingleTouch' 149.99 4
'MultiTouch' 199.99 5
'SuperGizmo' 49.99 49.99
See how it starts in the middle? 'Gizmo' is even missing its first apostrophe. Any idea what is happening? Am i missing something obvious?
**EDIT: Here is more code as requested. This is the if statement that eventually calls the function, the entire function, and the function declaration from my Table class. Thank you everyone for the help.
//Function definiton
void update_table(std::string table_name, std::string table_path, std::string set_schema, std::string set_item,
std::string where_schema, std::string where_item);
//From file that calls the function
if (text == "DELETE" || text == "Delete" || text == "delete")
{
//skips "from"
std::cin >> objName >> objName >> text;
if (objName.back() == ';')
{
objName = objName.substr(0, objName.size()-1);
}
if (text == "WHERE" || text == "Where" || text == "where")
{
std::cin >> del_name >> operation >> del_param;
if (del_param.back() == ';')
{
del_param = del_param.substr(0, del_param.size()-1);
}
table.delete_table_data(objName, use_DB, del_name, operation, del_param);
}
}
//The entire function
void Table::update_table(std::string table_name, std::string table_path, std::string set_schema, std::string set_item,
std::string where_schema, std::string where_item)
{
chdir(table_path.c_str());
filename = table_name + ".txt";
std::ifstream table (filename);
//init counter
if (table)
{
getline(table, table_data);
table_info.str(table_data);
table_info.clear();
buffer << table.rdbuf();
buffer.clear();
buffer.str();
table.clear();
//Unneccessary?
table.close();
std::ofstream table(filename);
//Finds size of table, writes table labels back to file.
num_table_items = 0;
modify_count = 0;
while(table_info >> item_name)
{
table_info >> item_type;
table << item_name << " " << item_type << "\t\t";
if (item_name == set_schema) // && item_name == where_schema
{
set_index = num_table_items;
}
if (item_name == where_schema)
{
where_index = num_table_items;
}
num_table_items++;
}
std::cout << buffer.str() << std::endl;
while (getline(buffer, table_data))
{
std::cout << table_data << std::endl;
temp_vec.push_back(table_data);
for (int i = 1; i < num_table_items; i++)
{
buffer >> table_data;
std::cout << "i = " << i << " Data = " << table_data << std::endl;
temp_vec.push_back(table_data);
}
if (temp_vec[where_index] == where_item)
{
modify_count++;
temp_vec[set_index] = set_item;
}
//store in vector
for (int i = 0; i < temp_vec.size(); i++)
{
table_vec.push_back(temp_vec[i]);
std::cout << temp_vec[i] << " ";
}
temp_vec.clear();
}
for (int i = 0; i < table_vec.size(); i++)
{
if (i % num_table_items == 0)
{
table << "\n" << table_vec[i] << "\t";
}
else if (i % num_table_items == num_table_items - 1)
{
table << table_vec[i];
}
else
{
table << table_vec[i] << "\t\t";
}
if (table_vec[i].length() < 8 && i % num_table_items != num_table_items - 1)
{
table << "\t";
}
}
table.close();
table_vec.clear();
table_info.clear();
table_info.str();
//write vector to file.
if (modify_count == 1)
{
std::cout << "-- " << modify_count << " record modified." << std::endl;
}
else
{
std::cout << "-- " << modify_count << " records modified." << std::endl;
}
}
else
{
std:: cout << "-- !Failed to query " << table_name << " because it does not exist" << std::endl;
}
}
the user input that should invoke this is:
update Product
set name = 'Gizmo'
where name = 'SuperGizmo';
or
update Product set price = 14.99 where name = 'Gizmo';
int main(int argc, char *argv[]) {
ifstream inFile;
int numOfLines = 0, numOfTokens = 0, numOfStrings = 0, maxStringLength = 0, l = 0, fileCount=0, mostCommonCount=0;
string inputFile, mostCommonList="", word;
for(int i = 1; i < argc; i++){
if(strpbrk(argv[i] , "-")){
if(flags.find(string(argv[i]))!=flags.end()) flags[string(argv[i])] = true;
else{
cerr << "INVALID FLAG " << argv[i] << endl;
exit(1);
}
}
else{
inFile.open(argv[i]);
fileCount++;
if(!inFile && fileCount==1){
cerr << "UNABLE TO OPEN " << argv[i] << endl;
exit(1);
}
else{
string line;
while(getline(inFile, line)) inputFile+=line+='\n';
if(fileCount>1){
cerr << "TOO MANY FILE NAMES" << endl;
exit(1);
}
}
}
}
int linenum = 0;
TType tt;
Token tok;
while((tok = getNextToken(&inFile, &linenum))!=DONE && tok != ERR){
tt = tok.GetTokenType();
word = tok.GetLexeme();
if(flags["-v"]==true){
(tt == ICONST||tt==SCONST||tt==IDENT) ? cout<<enumTypes[tok.GetTokenType()]<<"("<< tok.GetLexeme()<<")"<<endl : cout<< enumTypes[tok.GetTokenType()]<<endl;
}
if(flags["-mci"]==true){
if(tt==IDENT){
(identMap.find(word)!=identMap.end()) ? identMap[word]++ : identMap[word]=1;
if(identMap[word]>mostCommonCount) mostCommonCount = identMap[word];
}
}
if(flags["-sum"]==true){
numOfTokens++;
if(tt==SCONST){
numOfStrings++;
l = word.length();
if(l > maxStringLength) maxStringLength = l;
}
}
}
if(tok==ERR){
cout << "Error on line" << tok.GetLinenum()<<"("<<tok.GetLexeme()<<")"<<endl;
return 0;
}
if(flags["-mci"]==true){
cout << "Most Common Identifier: ";
if(!identMap.empty()){
word ="";
for(auto const& it : identMap){
if(it.second==mostCommonCount) word += it.first + ",";
}
word.pop_back();
cout << word << endl;
}
}
if(flags["-sum"]){
numOfLines = tok.GetLinenum();
numOfLines = tok.GetLinenum();
cout << "Total lines: " << numOfLines << endl;
cout << "Total tokens: " << numOfTokens << endl;
cout << "Total strings: " << numOfStrings << endl;
cout << "Length of longest string: " << maxStringLength << endl;
}
inFile.close();
return 0;
}
For some reason this code is running infinitely. I cannot figure out the source of error. I also do not know whether this file or the other linked file is causing this error so I posted the main program code. I think is one of the switch statements that causing this error but I am not sure. FYI: I am supposed to make a lexical analyzer so I had three files one lexigh.h (contains all the data types and all the functions), getToken.cpp(file that defines the functions from lexigh.h) and the main program which calls the methods and tests it.
I am writing a C++ code to calculate the code coverage and I want to used the OpenMP to help enhance my code by minimizing the overall run time by making the functions work in parallel so I can get less run time.
Can someone please tell me how and where to use the OpenMP?
int _tmain(int argc, _TCHAR* argv[])
{
std::clock_t start;
start = std::clock();
char inputFilename[] = "Test-Case-3.cs"; // Test Case File
char outputFilename[] = "Result.txt"; // Result File
int totalNumberOfLines = 0;
int numberOfBranches = 0;
int statementsCovered = 0;
float statementCoveragePercentage = 0;
double overallRuntime = 0;
ifstream inFile; // object for reading from a file
ofstream outFile; // object for writing to a file
inFile.open(inputFilename, ios::in);
if (!inFile) {
cerr << "Can't open input file " << inputFilename << endl;
exit(1);
}
totalNumberOfLines = NoOfLines(inFile);
inFile.clear(); // reset
inFile.seekg(0, ios::beg);
numberOfBranches = NoOfBranches(inFile);
inFile.close();
statementsCovered = totalNumberOfLines - numberOfBranches;
statementCoveragePercentage = (float)statementsCovered * 100/ totalNumberOfLines;
outFile.open(outputFilename, ios::out);
if (!outFile) {
cerr << "Can't open output file " << outputFilename << endl;
exit(1);
}
outFile << "Total Number of Lines" << " : " << totalNumberOfLines << endl;
outFile << "Number of Branches" << " : " << numberOfBranches << endl;
outFile << "Statements Covered" << " : " << statementsCovered << endl;
outFile << "Statement Coverage Percentage" << " : " << statementCoveragePercentage <<"%"<< endl;
overallRuntime = (std::clock() - start) / (double)CLOCKS_PER_SEC;
outFile << "Overall Runtime" << " : " << overallRuntime << " Seconds"<< endl;
outFile.close();
}
i want to minimize the time taken to count the number of branches by allowing multiple threads to work in parallel to calculate the number faster? how can i edit the code so that i can use the open mp and here you can find my functions:bool is_only_ascii_whitespace(const std::string& str)
{
auto it = str.begin();
do {
if (it == str.end()) return true;
} while (*it >= 0 && *it <= 0x7f && std::isspace(*(it++)));
// one of these conditions will be optimized away by the compiler,
// which one depends on whether char is signed or not
return false;
}
// Function 1
int NoOfLines(ifstream& inFile)
{
//char line[1000];
string line;
int lines = 0;
while (!inFile.eof()) {
getline(inFile, line);
//cout << line << endl;
if ((line.find("//") == std::string::npos)) // Remove Comments
{
if (!is_only_ascii_whitespace(line)) // Remove Blank
{
lines++;
}
}
//cout << line << "~" <<endl;
}
return lines;
}
// Function 2
int NoOfBranches(ifstream& inFile)
{
//char line[1000];
string line;
int branches = 0;
while (!inFile.eof()) {
getline(inFile, line);
if ((line.find("if") != std::string::npos) || (line.find("else") != std::string::npos))
{
branches++;
}
}
return branches;
}
I use a while loop with the find function in c++ but I need to use the position found like the condition of the while loop but Visual Studio shome me
An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occured in Test.exe
Additional information: External component has thrown an exception.
I use this code:
int dim=myString.length();
while (dim>=0)
{
size_t pos1 = myString.find("<article");
size_t pos2 = myString.find("</article>");
std::string buf = myString.substr(pos1, pos2 - pos1 + 10);
myString = myString.substr(pos2 + 10);
ofstream myfile("body.txt");
if (myfile.is_open())
{
myfile << myString;
myfile.close();
}
else cout << "Unable to open file";
//cout << myString << endl;
ptree xmlTree;
string title[1000];
int j = 0;
try
{
stringstream ss;
ss << buf;
read_xml(ss, xmlTree);
const ptree & formats = xmlTree.get_child("article", empty_ptree());
BOOST_FOREACH(const ptree::value_type & f, formats)
{
string at = f.first + ATTR_SET;
const ptree & attributes = f.second.get_child("<xmlattr>", empty_ptree());
//cout << "Extracting attributes from " << at << ":" << endl;
BOOST_FOREACH(const ptree::value_type &v, attributes)
{
string first = v.first.data();
//cout << "First: " << v.first.data() << " Second: " << v.second.data() << endl;
if (first == "title")
{
title[j] = v.second.data();
j++;
}
}
}
for (int a = 0; a < j; a++)
{
cout << title[a] << endl;
}
}
catch (xml_parser_error &e) {
cout << "Failed to read config xml " << e.what() << endl;
}
catch (...) {
cout << "Failed to read config xml with unknown error" << endl;
}
dim = dim - pos2;
}
what is the problem?
I resolve my problem thanks to the help of PaulMcKenzie. I modify my code to insert a boolean variable and to control if pos1 and pos2 find the correct string which are <article and </article>.
This is the code:
int dim = myString.length();
boolean in=true;
while (in==true)
{
size_t pos1 = myString.find("<article");
size_t pos2 = myString.find("</article>");
if (pos1 != std::string::npos && pos2 != std::string::npos)
{
std::string buf = myString.substr(pos1, pos2 - pos1 + 10);
myString = myString.substr(pos2 + 10);
ofstream myfile("body.txt");
if (myfile.is_open())
{
myfile << myString;
myfile.close();
}
else cout << "Unable to open file";
//some code
dim = dim - myString.length();
in = true;
}
else
{
in = false;
cout << " - - - - - - - - - - " << endl;
}
}
i have a c++ program to get last line data of issuance.csv file(has id , date,time) and write new record on it
but when i try to write new data(like id,time,date) on it ,save blank line without data on issuance.csv file ,what should i do??
#define DEFAULT_ID "2000"
#define ISSUE_FILE_ADDRESS "/home/pi/file/issuance.csv"
int WriteNewRecord(string NewID, string NewCustomerID, string NewIssueDate)
{
fstream FileStream;
FileStream.open(ISSUE_FILE_ADDRESS, fstream::app | fstream::out);//Just for write into file
if(!FileStream.is_open())
{
cout << "File Open Error1" << endl;
return -1;
}
FileStream << NewID << "," << NewCustomerID << "," << NewIssueDate << endl;//Just for write into file
FileStream.close();
return 0;
}
int GetLastData(string& LastID, string& LastCustomerID, string& LastDate, string& LastTime)
{
fstream FileStream;
FileStream.open(ISSUE_FILE_ADDRESS, fstream::in);
if(!FileStream.is_open())
{
cout << "File Open Error2" << endl;
return -1;
}
string Line;
int Indices[3];
getline(FileStream, Line);
if(Line.length())
{
do {
Indices[0] = Line.find(",");
Indices[1] = Line.find(",", Indices[0] + 1);
Indices[2] = Line.find(",", Indices[1] + 1);
LastID = Line.substr(0, Indices[0]);
LastCustomerID = Line.substr(Indices[0] + 1, Indices[1] - Indices[0] - 1);
LastDate = Line.substr(Indices[1] + 1, Indices[2] - Indices[1] - 1);
LastTime = Line.substr(Indices[2] + 1, Line.length() - Indices[2] - 1);
getline(FileStream, Line);
} while (Line.length());
}
else
LastID = DEFAULT_ID;
FileStream.close();
return 0;
}
int time(){
time_t currentTime;
struct tm *localTime;
time( ¤tTime ); // Get the current time
localTime = localtime( ¤tTime ); // Convert the current time to the local time
int Day = localTime->tm_mday;
int Month = localTime->tm_mon + 1;
int Year = localTime->tm_year + 1900;
int Hour = localTime->tm_hour;
int Min = localTime->tm_min;
int Sec = localTime->tm_sec;
cout << Day << "/" << Month << "/" << Year << ", "<< Hour << ":" << Min << ":" << Sec<<endl;
//std::cout << std::endl;
return (currentTime);
}
int main()
{
string ID,CustomerID,Date,Time;
if(!GetLastData(ID, CustomerID, Date,Time))
{
cout << ID << " " << CustomerID << " " << Date << " " << Time << endl;
//Issuance Operation...
//...
//...
// if(!WriteNewRecord("2008", "100000", "4/29/2015" , "10:55:15"))//Example for test
string NewID,NewCustomerID,NewIssueDate;
if(!WriteNewRecord(NewID, NewCustomerID, NewIssueDate))
{
unsigned int new_id = atoi(ID.c_str()) + 1;
char tmp[5];
sprintf(tmp, "%d", new_id);
NewID = string(tmp);
tmp[4] = 0;
NewCustomerID=CustomerID;
char write[4];
unsigned int new_date=time();
memcpy(write,&new_date,2);
//cout << write << endl;
sscanf ( NewIssueDate.c_str(), "%d", &new_date );
cout<< NewIssueDate<<"," << NewCustomerID<<","<< NewID <<endl;
//cout << NewIssueDate<<endl;
return 0;
}
}
}
If you look at your code, you do
string NewID,NewCustomerID,NewIssueDate, NewIssueTime;
if(!WriteNewRecord(NewID, NewCustomerID, NewIssueDate))
{
// Initialize variable but don't write them to the file
}
When you declare the std::string variables, they are initialized to be empty, so writing them to a file will write nothing. You then initialize the variables, after you write them to the file.
You could try using FileStream.seekp (std::ios::end); before writing