Missing data inside the dat file after writing operation - missing-data

I am trying to save the data the user inputted inside a linked-list and then store those data inside a file so that I can retrieve them back when I enter the 2nd option(as per in the int main()). Unfortunately, after I wrote the data into the file and check back the file, I found out that my data is missing and the file is filled with garbage.so I cant retrieve the data back. Is there any solution to this problem?? Thank you.
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<fstream>
using namespace std;
fstream fp;
class List{
private:
struct node{
string name;
string surname;
int idNum;
string nationality;
int number;
node *next;
}nod;
node* head;
node* curr;
node* temp;
public:
List();
bool isEmpty(node *head){
if(head==NULL){
return true;
}
else
return false;
}
void AddNode(string addName,string addsurName,int addId,string addNation,int addNumber);
void insertAsFirst(string addName,string addsurName,int addId,string addNation,int addNum);
//void DeleteNode(int delData);
void printList();
void write_linky(string name,string surName,int idNum,string nation,int number);
void read_linky();
}lb;
List::List(){
head=NULL;
curr=NULL;
temp=NULL;
}
void List::insertAsFirst(string addName,string addsurName,int addId, string addNation,int addNum){
node *n = new node;
n->name=addName;
n->surname=addsurName;
n->idNum=addId;
n->nationality=addNation;
n->number=addNum;
n->next = NULL;
head = n;
//last = temp;
}
void List::AddNode(string addName,string addsurName,int addId,string addNation,int addNum){
if(isEmpty(head)){
insertAsFirst(addName,addsurName,addId,addNation,addNum);
}
else{
node* n = new node;
n->next=NULL;
n->name=addName;
n->surname=addsurName;
n->idNum=addId;
n->nationality=addNation;
n->number=addNum;
curr = head;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = n;
}
}
void List::printList(){
curr=head;
cout << "\n\t\t\t\t CUSTOMER INFO" << endl << endl;
cout <<"NAME" << setw(20) << "SURNAME" << setw(20) << "ID NO. " << setw(20) << "NATIONALLITY" << setw(20) << "TELEPHONE" << endl << endl;
while(curr != NULL){
cout << curr -> name << setw(20) << curr -> surname << setw(20) << curr -> idNum << setw(20) << curr -> nationality << setw(20) << curr -> number << endl << endl;
curr=curr->next;
/*cout<<curr->number << endl;
cout<<curr->age << endl;
cout<<curr->idNum << endl;
cout<<curr->name<< endl;
cout<<curr->surname << endl;
cout<<curr->nationality << endl;
curr = curr->next;
}
*/
}
}
void List::write_linky(string name,string surName,int idNum,string nation,int number)
{
fp.open("Link.dat",ios::out|ios::app);
lb.AddNode(name,surName,idNum,nation,number);
lb.printList();
fp.write((char*)&nod,sizeof(node));
fp.close();
cout<<"\n\nThe Data Has Been Added ";
}
void List::read_linky(){
fp.open("Link.dat",ios::in);
while(fp.read((char*)&nod,sizeof(node)))
{
lb.printList();
//cout<<"\n\n=====================================================\n";
//getch();
}
fp.close();
//getch();
}
int main(){
List lb;
int idNum,number;
string name,surname,nationality;
char choice,ch;
cout<<"Please select your choice"<<endl;
cout<<"1.Book ticket"<<endl;
cout<<"2.view details"<<endl;
cin>>ch;
switch(ch){
case '1':
do{
cout<< "Enter name: ";
cin>>name;
cout<< "Enter surname: ";
cin>>surname;
cout<< "Enter identification number: ";
cin>>idNum;
cout<< "Enter your nationality: ";
cin>>nationality;
cout<< "Enter contact number: ";
cin>>number;
lb.write_linky(name,surname,idNum,nationality,number);
//lb.AddNode(number,age,idNum,name,surname,nationality);
cout<<"\n\nDo you want to add more entry?";
cin>>choice;
}while(choice=='y');
break;
case '2':
lb.read_linky();
break;
}
}
//lb.printList();

I've never done this but I'd guess string is a complex structure that doesn't lend itself to being written to disk like this. As a test change these to (say) char[255] and it might be happier.

Related

Defining strict_real_policies for reals with a comma decimal character

I would like to create a custom policy derived from strict_real_policies that will parse reals, such as "3,14", i.e. with a comma decimal point as used e.g. in Germany.
That should be easy, right?
#include <iostream>
#include <string>
#include <boost/spirit/home/x3.hpp>
template <typename T>
struct decimal_comma_strict_real_policies:boost::spirit::x3::strict_real_policies<T>
{
template <typename Iterator>
static bool
parse_dot(Iterator& first, Iterator const& last)
{
if (first == last || *first != ',')
return false;
++first;
return true;
}
};
void parse(const std::string& input)
{
namespace x3=boost::spirit::x3;
std::cout << "Parsing '" << input << "'" << std::endl;
std::string::const_iterator iter=std::begin(input),end=std::end(input);
const auto parser = x3::real_parser<double, decimal_comma_strict_real_policies<double>>{};
double parsed_num;
bool result=x3::parse(iter,end,parser,parsed_num);
if(result && iter==end)
{
std::cout << "Parsed: " << parsed_num << std::endl;
}
else
{
std::cout << "Something failed." << std::endl;
}
}
int main()
{
parse("3,14");
parse("3.14");
}

Apache thrift multi client server

I am writing simple chat in Qt + Apache Thrift but right now I need to face a problem with connecting multiple clients. On first sight everything looks good and I cannot find where the problem is.
Here is my server main.cpp:
int main(int argc, char **argv)
{
int port = 9090;
::apache::thrift::stdcxx::shared_ptr<UsersStorageHandler> handler(new UsersStorageHandler());
::apache::thrift::stdcxx::shared_ptr<TProcessor> processor(new UsersStorageProcessor(handler));
::apache::thrift::stdcxx::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
::apache::thrift::stdcxx::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
::apache::thrift::stdcxx::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
std::cout << "Users server started..." << std::endl;
std::cout << std::endl;
std::cout << std::endl;
server.serve();
return 0;
}
Here is my server handler.h:
class UsersStorageHandler : virtual public UsersStorageIf
{
public:
UsersStorageHandler();
int32_t subscribeUser(const std::string& username);
void unsubscribeUser(const int32_t userID);
private:
Users users;
};
Here is my server handler.cpp:
UsersStorageHandler::UsersStorageHandler()
{
srand(time(NULL));
}
int32_t UsersStorageHandler::subscribeUser(const std::string &username)
{
++idGenerator;
assert(username != "");
User user;
user.userId = idGenerator;
user.username = username;
user.colorR = (rand() % 255) + 0;
user.colorG = (rand() % 255) + 0;
user.colorB = (rand() % 255) + 0;
user.colorA = 0;
users[idGenerator] = user;
std::cout << "NEW USER CONNECTED" << std::endl;
std::cout << "==================" << std::endl;
std::cout << "Username:\t" << user.username << std::endl;
std::cout << "User ID:\t" << user.userId << std::endl;
std::cout << "User R:\t" << user.colorR << std::endl;
std::cout << "User G:\t" << user.colorG << std::endl;
std::cout << "User B:\t" << user.colorB << std::endl;
std::cout << "User A:\t" << user.colorA << std::endl;
std::cout << "==================" << std::endl;
std::cout << "CURRENT USERS COUNT:\t" << users.size() << std::endl;
std::cout << std::endl;
std::cout << std::endl;
/*
* SEND TO CLIENT INFO ABOUT NEW USER HERE
*/
return idGenerator;
}
void UsersStorageHandler::unsubscribeUser(const int32_t userID)
{
auto index = users.find(userID);
assert(index != users.end());
users.erase(index);
std::cout << "USER DISCONNECTED" << std::endl;
std::cout << "=================" << std::endl;
std::cout << "USER WITH ID " << userID << " ERASED" << std::endl;
std::cout << "USERS COUNT:\t" << users.size() << std::endl;
std::cout << std::endl;
std::cout << std::endl;
/*
* SEND TO CLIENT INFO ABOUT NEW USER HERE
*/
}
And right here is a method for connect to the server in client app:
void MainWindow::connectToServers(const std::string &ip, const uint32_t &port, const std::string &nick)
{
m_usersServerIP = ip;
m_usersServerPort = port;
try
{
::apache::thrift::stdcxx::shared_ptr<TTransport> socket(new TSocket(m_usersServerIP, m_usersServerPort));
::apache::thrift::stdcxx::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
::apache::thrift::stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
m_usersServerClient = std::make_shared<UsersStorageClient>(protocol);
transport->open();
m_clientID = m_usersServerClient.get()->subscribeUser(nick);
QMessageBox::information(this, "Connected",
"You are connected "
"with users server");
createAndRegisterUsersServerReactor();
activateChatScreen();
}
catch (const std::exception &e)
{
qDebug() << e.what();
}
qDebug() << "ID FROM SERVER:\t" << m_clientID;
}
As far as I checked right now it is working like this:
Created two instances of client app. In one instance fill nickname, ip, port and clicked connect (connectToServers method). Client connected. In another instance done the same but after clicked connected ... nothing happens. App freezes at this line:
m_clientID = m_usersServerClient.get()->subscribeUser(nick);
After closing first client, second one connects to the server.
A TSimplerServer supports a single connection. You should try using TThreadedServer to support multiple simultaneous clients.
As Chris mentioned above either make a Threaded server to server multiple requests simultaneously. For me I have created a non-blocking server as below to be able to serve multiple clients in async manner for loose coupling.
public static void start(dataClass configData, String env, int port) throws TTransportException {
TNonblockingServerTransport transport = new TNonblockingServerSocket(port);
TNonblockingServer.Args nBlockServer = new TNonblockingServer.Args(transport);
ccmProviderServiceImpl impl = new ccmProviderServiceImpl(configData, env);
Processor<ccmProviderServiceImpl> processor = new ccmProviderService.Processor<>(impl);
TServer server = new TNonblockingServer(nBlockServer.processor(processor));
//custom event handling for tracking
ccmServerEventHandler cse = new ccmServerEventHandler();
server.setServerEventHandler(cse);
server.serve();
}

How to generate binary tree dot file for Graphviz from C++

I have implemented a Binary Search Tree in C++ which support dynamically creating and deleting nodes. To visualize the tree, I firstly tried displaying edges with / and \. However, this gives really awful visualization, as the position of / and \ needs to be calculated precisely. The current figures are as follows:
So I found a tool called Graphviz. The raw language supported by Graphviz is dot language, which I am not familiar with.
I read the documentation and found the dot language easy to write and read, but I still want to use my C++ code to generate the tree as this contains much content such as inserting according to user's input.
Is there any chance to use some function to generate the dot file?
The code of my binary tree:
//BTNode.h
#include <iostream>
using namespace std;
template<class T>
struct BTNode{
BTNode(){
lChild = rChild = NULL;
}
BTNode(const T& x){
element = x;
lChild = rChild = NULL;
}
BTNode(const T& x, BTNode<T>* l, BTNode<T>* r){
element = x;
lChild = l;
rChild = r;
}
T element;
int digit, row;
BTNode<T>* lChild, *rChild;
};
//BSTree.h
#include"ResultCode.h"
#include "BTNode.h"
#include "seqqueue.h"
#include <math.h>
template <class T>
class BSTree
{
public:
BSTree(){ root = NULL; }
ResultCode SearchByRecursion(T& x)const;
ResultCode Insert(T& x);
ResultCode Remove(T& x);
void InOrder(void(*Visit)(T& x));
ResultCode SearchByIteration(T& x);
void GradeOrder(void(*Visit)(T &x), BTNode<T> *t, int height);
BTNode<T>* root;
void printSpace(int num);
int GetHeight();
int GetHeight(BTNode<T> *t);
int **A;
private:
ResultCode SearchByRecursion(BTNode<T> *p, T& x)const;
void InOrder(void(*Visit)(T& x), BTNode<T> *t);
};
template <class T>
ResultCode BSTree<T>::SearchByRecursion(T &x)const{
return SearchByRecursion(root, x);
}
template <class T>
ResultCode BSTree<T>::SearchByRecursion(BTNode<T> *p, T& x)const{
if (!p) return NotPresent;
else if (x < p->element) return SearchByRecursion(p->lChild, x);
else if (x > p->element) return SearchByRecursion(p->rChild, x);
else{
x = p->element;
return Success;
}
}
template <class T>
ResultCode BSTree<T>::SearchByIteration(T& x){
BTNode<T> *p = root;
while (p)
if (x < p->element) p = p->lChild;
else if (x > p->element) p = p->rChild;
else{
x = p->element;
return Success;
}
return NotPresent;
}
template<class T>
ResultCode BSTree<T>::Insert(T& x){
BTNode<T> *p = root, *q = NULL;
while (p){
q = p;
if (x < p->element) p = p->lChild;
else if (x > p->element) p = p->rChild;
else { x = p->element; return Duplicate; }
}
p = new BTNode<T>(x);
if (!root) root = p;
else if (x < q->element) q->lChild = p;
else q->rChild = p;
return Success;
}
template <class T>
ResultCode BSTree<T>::Remove(T& x){
BTNode<T> *c, *s, *r, *p = root, *q = NULL;
while (p && p->element != x){
q = p;
if (x < p->element) p = p->lChild;
else p = p->rChild;
}
if (!p) return NotPresent;
x = p->element;
if (p->lChild&&p->rChild)
{
s = p->rChild;
r = p;
while (s->lChild){
r = s; s = s->lChild;
}
p->element = s->element;
p = s; q = r;
}
if (p->lChild)
c = p->lChild;
else c = p->rChild;
if (p == root)
root = c;
else if (p == q->lChild)
q->lChild = c;
else q->rChild = c;
delete p;
return Success;
}
template <class T>
void BSTree<T>::InOrder(void(*Visit)(T &x)){
InOrder(Visit, root);
}
template <class T>
void BSTree<T>::InOrder(void(*Visit)(T &x), BTNode<T> *t){
if (t){
InOrder(Visit, t->lChild);
Visit(t->element);
InOrder(Visit, t->rChild);
}
}
template <class T>
void BSTree<T>::GradeOrder(void(*Visit)(T &x), BTNode<T> *t, int height)
{
A = new int*[height];
for (int i = 0; i < height; i++){
A[i] = new int[(int)pow(2, height) - 1];
}
for (int i = 0; i < height; i++)
for (int j = 0; j < (int)pow(2, height) - 1; j++){
A[i][j] = -1;
}
SeqQueue<BTNode<T>*> OrderQueue(10);
BTNode<T> * loc = t;
loc->row = 0;
loc->digit = 0;
if (loc){
OrderQueue.EnQueue(loc);
A[loc->row][loc->digit] = loc->element;
}
while (!OrderQueue.IsEmpty())
{
OrderQueue.Front(loc);
OrderQueue.DeQueue();
if (loc->lChild)
{
A[(loc->row) + 1][2 * (loc->digit)] = loc->lChild->element;
loc->lChild->row = (loc->row) + 1;
(loc->lChild->digit) = (loc->digit) * 2;
OrderQueue.EnQueue(loc->lChild);
}
if (loc->rChild)
{
A[(loc->row) + 1][2 * (loc->digit) + 1] = loc->rChild->element;
loc->rChild->row = (loc->row) + 1;
(loc->rChild->digit) = (loc->digit) * 2 + 1;
OrderQueue.EnQueue(loc->rChild);
}
}
cout << endl;
int total = (int)(pow(2, height)) - 1;
for (int i = 0; i < height; i++){
if (i != 0){
cout << endl;
}
int space1 = (total / (int)(pow(2, i + 1)));
int space2;
if (i == 0){
space2 = 0;
}
else{
space2 = (total - 2 * space1 - (int)pow(2, i)) / (int)(pow(2, i) - 1);
}
printSpace(space1);
for (int j = 0; j < (int)pow(2, i); j++){
if (A[i][j] != -1){
cout << A[i][j];
}
else{
cout << " ";
}
printSpace(space2);
}
printSpace(space1);
cout << endl;
}
}
template <class T>
void BSTree<T>::printSpace(int num){
for (int i = 0; i < num; i++){
cout << " ";
}
}
template<class T>
int BSTree<T>::GetHeight()
{
return GetHeight(root);
}
template<class T>
int BSTree<T>::GetHeight(BTNode<T> *t)
{
if (!t)return 0;
if ((!t->lChild) && (!t->rChild)) return 1;
int lHeight = GetHeight(t->lChild);
int rHeight = GetHeight(t->rChild);
return (lHeight > rHeight ? lHeight : rHeight) + 1;
}
template <class T>
void Visit(T& x){
cout << x << " ";
}
//main.cpp
#include <iostream>
#include "BSTree4.h"
#include<Windows.h>
int getDigit(int x);
int main(){
BSTree<int> bt;
int number;
// char choice;
cout << "Welcome to BSTree System, to begin with, you need to create a tree!(Press enter to continue...)" << endl;
getchar();
cout << "Please enter the size of the Binary Search Tree:";
cin >> number;
int *ToBeInserted = new int[number];
cout << "Enter the number of each Node(size:" << number << "):";
for (int i = 0; i < number; i++){
cin >> ToBeInserted[i];
}
cout << "OK,now the tree will be created!" << endl;
for (int i = 0; i < number; i++){
cout << "Inserting Node " << i;
for (int k = 0; k < 3; k++){
cout << ".";
//Sleep(200);
}
showResultCode(bt.Insert(ToBeInserted[i]));
//Sleep(500);
}
cout << "Done." << endl;
//Sleep(500);
int height = bt.GetHeight();
bt.GradeOrder(Visit, bt.root,height);
int a;
cout << "please enter the number to search:";
cin>>a;
showResultCode(bt.SearchByRecursion(a));
bt.GradeOrder(Visit, bt.root,height);
if (bt.SearchByRecursion(a) == 7){
cout << "Now delete the number" << "..." << endl;
showResultCode(bt.Remove(a));
bt.GetHeight();
cout << "Deleted!Now the tree is:" << endl;
bt.GradeOrder(Visit, bt.root, height);
bt.InOrder(Visit);
cout << endl;
}
return 0;
}
//resultcode.h
#include<iostream>
using namespace std;
enum ResultCode{ NoMemory, OutOfBounds, Underflow, Overflow, Failure,
NotPresent, Duplicate, Success };
void showResultCode(ResultCode result)
{
int r = (int)result;
switch (result)
{
case 0:cout << "NoMemory" << endl; break;
case 1:cout << "OutOfBounds" << endl; break;
case 2:cout << "Underflow" << endl; break;
case 3:cout << "Overflow" << endl; break;
case 4:cout << "Failure" << endl; break;
case 5:cout << "NotPresent" << endl; break;
case 6:cout << "Duplicate" << endl; break;
case 7:cout << "Success" << endl; break;
default: cout << "Exception occured:unknown resultcode" << endl;
}
}
Update: I have solved the problem myself, check the answer below.
The key elements in dot language file in this problem are nodes and edges. Basically the dot file structure for a binary tree would be like the following:
digraph g {
//all the nodes
node0[label="<f0>|<f1> value |<f2>"]
node1[label="<f0>|<f1> value |<f2>"]
node2[label="<f0>|<f1> value |<f2>"]
...
//all the edges
"node0":f2->"node4":f1;
"node0":f0->"node1":f1;
"node1":f0->"node2":f1;
"node1":f2->"node3":f1;
...
}
The following output of the dot file can be used to understand the structure:
Explanation for the dot file:
For the node part node0[label="<f0>|<f1> value |<f2>"] means the node called node0 has three parts: <f0> is the left part, <f1> is the middle part with a value, <f2> is the right part. This just corresponds to leftchild, value and rightchild in a binary node.
For the edges part, "node0":f2->"node4":f1; means the right part of node0(i.e.<f2>) points to the middle part of node4 (i.e. <f1>).
Therefore, the way to generate the dot file is simply through a traverse of a binary tree. Any method is fine. (BFS,DFS...) All we need is to add the code to write the nodes and corresponding edges into file when we do the traverse. I personally used BFS with level order traverse of a binary tree to implement which is shown below as a function called showTree.
void showTree(BSTree<int> &bst,int total,int *Inserted){
char filename[] = "D:\\a.gv"; // filename
ofstream fout(filename);
fout << "digraph g{" << endl;
fout << "node [shape = record,height = .1];" << endl;
SeqQueue<BTNode<int>*> OrderQueue(1000);
BTNode<int> * loc = bst.root;
loc->row = 0;
loc->digit = 0;
int num = 0;
if (loc){
OrderQueue.EnQueue(loc);
loc->ID = num++;
fout << " node" << loc->ID << "[label = \"<f0> |<f1>" << loc->element << "|<f2>\"];" << endl;
}
while (!OrderQueue.IsEmpty())
{
OrderQueue.Front(loc);
OrderQueue.DeQueue();
if (loc->lChild)
{
loc->lChild->row = (loc->row) + 1;
(loc->lChild->digit) = (loc->digit) * 2;
OrderQueue.EnQueue(loc->lChild);
loc->lChild ->ID= (num++);
fout << " node" << loc->lChild->ID << "[label = \"<f0> |<f1>" << loc->lChild->element << "|<f2>\"];" << endl;
//cout << loc->ID;
}
if (loc->rChild)
{
loc->rChild->row = (loc->row) + 1;
(loc->rChild->digit) = (loc->digit) * 2 + 1;
OrderQueue.EnQueue(loc->rChild);
loc->rChild->ID = (num++);
fout << " node" << loc->rChild->ID << "[label = \"<f0> |<f1>" << loc->rChild->element << "|<f2>\"];" << endl;
//cout << loc->ID;
}
}
//begin to draw!
SeqQueue<BTNode<int>*> OrderQueue2(1000);
BTNode<int> * loc2 = bst.root;
loc2->row = 0;
loc2->digit = 0;
if (loc2){
OrderQueue2.EnQueue(loc2);
}
while (!OrderQueue2.IsEmpty())
{
OrderQueue2.Front(loc2);
OrderQueue2.DeQueue();
if (loc2->lChild)
{
loc2->lChild->row = (loc2->row) + 1;
(loc2->lChild->digit) = (loc2->digit) * 2;
OrderQueue2.EnQueue(loc2->lChild);
cout << "\"node" << loc2->ID << "\":f0->\"node" << loc2->lChild->ID << "\":f1;" << endl;
cout << loc2->lChild->element << endl;
fout << "\"node" << loc2->ID << "\":f0->\"node" << loc2->lChild->ID << "\":f1;" << endl;
}
if (loc2->rChild)
{
loc2->rChild->row = (loc2->row) + 1;
(loc2->rChild->digit) = (loc2->digit) * 2 + 1;
OrderQueue2.EnQueue(loc2->rChild);
cout << "\"node" << loc2->ID << "\":f2->\"node" << loc2->rChild->ID << "\":f1;" << endl;
cout << loc2->rChild->element << endl;
fout << "\"node" << loc2->ID << "\":f2->\"node" << loc2->rChild->ID << "\":f1;" << endl;
}
}
fout << "}" << endl;
}
And the final output:

Saving input to variable so after the program closes it will remember the input

I am making a program that stores a default password that when entered correctly you can change it. Problem is when I enter the new password it doesn't save when I close and open the program.
#include<iostream>
#include<sstream>
using namespace std;
string inputC;
string yes = "yes";
string no = "no";
string password;
string input;
void correct()
{
cout << "Would you like to change the password?" << endl;
cin >> inputC;
if (inputC == yes)
{
cout << "Enter new password:" << endl;
cin >> password;
}
else
{
cout << "You now have access." << endl;
}
}
void enter()
{
cout << "Enter password: " << endl;
cin >> input;
if (input == password)
{
cout << "Correct" << endl;
correct();
}
else
{
cout << "Incorrect" << endl;
enter();
}
}
int main()
{
if (password.empty())
{
password = "password";
}
enter();
}
http://pastebin.com/zhKTW2FB
As far as I know, variables you create with code go to RAM Memory, so they are destroyed as soon as your programs finishes. In order to keep the new password, you should consider having it written in an external text file or database.

ad hoc scanner just wont work

So far i have this code that is suppose to be an ad hoc scanner, im not sure where exactly the problem is because i get a very odd error in the output.txt file. it all starts when the program hits the left parenthesis, is there somthing wrong with my checkforoperators function? i have looked but have found little and have even asked others, but no reall luck as to what the problem is.
the input file contains this
read A1
read A2
sum:=(A1-33)+A2*5.5
write sum
write (A1+A2)/2
and the output file is SUPPOSE to look like this
read
A1
read
A2
Sum
:=
(
A1
-
33
)
+
A2
*
5.5
write
sum
write
(
A1
+
A2
)
/
2
heres the main file
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
// This program is an ad-hoc scanner.
// It will recognize tokens and seperate them.
// this language will NOT DISTINGUISH between uppercase or lowercase.
void stripSpacing(string &);
void checkForCommands();
void checkForLetters();
void checkForOperators();
void checkForAssignment();
void checkForDecimal();
void checkForDigit();
int x1 = 0;
int x2 = 0;
int vars[10];
// Only for demonstration purposes, we could use a dynamic array for larger purposes.
string holder;
// used to hold the current string before processing.
fstream handling;
// file handling from other libraries.
fstream output;
char temp1[1];
char temp2[1];
int x = 0;
int xtemp = 0;
int main()
{
output.open("output.txt");
handling.open("input.txt");
if (handling.is_open())
{
while (!handling.eof())
{
dcom:
getline (handling,holder);
if(holder[x] == '/' && holder[x+1] == '/')
{
cout << "This line has only comments.... REMOVED :)" << endl;
//do nothing :)
goto dcom;
}
cout << endl;
stripSpacing(holder);
cout << "The line is this long after removing spaces: " << holder.length() << endl;
cout << "The line contains: " << holder << endl;
cout << endl;
while(holder.length() != x)
{
// let's check for commands, such as read write or sum.
checkForOperators();
checkForAssignment();
checkForDecimal();
checkForDigit();
checkForCommands();
checkForLetters();
}
output << "\n";
x=0;
}
handling.close();
output.close();
return 0;
}
}
void stripSpacing(string &str)
{
for (int i=0; i<str.length(); i++)
if (str[i]==' ')
{
str.erase(i,1);
i--;
}
}
void checkForOperators()
{
if(holder[x] == '(' || holder[x] == ')'|| holder[x] == '+' || holder[x] == '-' || holder[x] == '*' ||holder[x] == '/')
{
output << holder[x] + "\n";
x++;
}
cout << "checkForOpertors" << endl;
}
void checkForCommands()
{
xtemp = x;
if(holder[x] == 'w')
{
x++;
if(holder[x] == 'r')
{
x++;
if(holder[x] == 'i')
{
x++;
if(holder[x] == 't')
{
x++;
if(holder[x] == 'e')
{
x++;
output << "write\n"; goto stop;
}else{x=xtemp; goto stop;}
}else{x=xtemp; goto stop;}
}else{x=xtemp; goto stop;}
}else{x=xtemp; goto stop;}
}
if(holder[x] == 'r')
{
x++;
if(holder[x] == 'e')
{
x++;
if(holder[x] == 'a')
{
x++;
if(holder[x] == 'd')
{
x++;
output << "read\n"; goto stop;
}else{x=xtemp; goto stop;}
}else{x=xtemp; goto stop;}
}else{x=xtemp; goto stop;}
}
if(holder[x] == 's')
{
x++;
if(holder[x] == 'u')
{
x++;
if(holder[x] == 'm')
{
x++;
output << "sum\n"; goto stop;
}else{x=xtemp; goto stop;}
}else{x=xtemp; goto stop;}
}
stop:
cout << "checkForCommand" << endl;
}
void checkForLetters()
{
if(isalpha(holder[x]))
{
output << holder[x];
x++;
}
cout << "checkForLetters" << endl;
}
void checkForAssignment()
{
if(holder[x] == ':')
{
x++;
if(holder[x] == '=')
{
output << ":=\n";
x++;
}
else
{
cout << "ERROR!!! NO : BEFORE =" << endl;
}
}
cout << "checkForAssign" << endl;
}
void checkForDecimal()
{
if(holder[x] == '.')
{
x++;
if(isdigit(holder[x]))
{
output << '.';
x--;
}
}
cout << "checkForDeci" << endl;
}
void checkForDigit()
{
if(isdigit(holder[x]))
{
output << holder[x];
x++;
}
cout << "checkForDig" << endl;
}