C++. Doesn't seem to take input from the user - c++

So I'm new to C++. The idea is that it's supposed to give the user two options, and either option reads input from the user. However, neither of them actually reads any input from the user and instead just skips to the end of the program. Any help is really appreciated! Thank you.
(Note: I know it has something to do with the first 'cin' taking in the 'number')
#include <stdio.h>
#define SIZE 80
#include <iostream>
int main(void)
{
FILE * pFile;
int c; // variable to hold character input by user
char sentence[SIZE]; // create char array
char filename[SIZE]; //create filename array
int i = 0; // initialize counter i
int number;
std::cout << "Give a number. 1 for file. Anything else for standard.";
std::cin >> number;
std::cin.clear();
if(number==1)
{
puts("Enter filename to append: ");
while ((i < SIZE-1) && (c = getchar()) != '\n') {
filename[i++] = c;}
filename[i]= '\0';
//fgetc(sentence,80,stdin);
pFile=fopen(filename,"a");
puts("Give a sentence to place in file:");
while ((i < SIZE-1) && (c = getchar()) != '\n') {
sentence[i++] = c;}
sentence[i]= '\0';
fputs(sentence,pFile);
fclose(pFile);
do {
c = fgetc (pFile);
} while (c != EOF);
fclose (pFile);
}
else
{
// prompt user to enter line of text
puts("Enter a line of text:");
// use getchar to read each character
while ((i < SIZE-1) && (c = getchar()) != '\n') {
sentence[i++] = c;}
sentence[i]= '\0';
// terminate string
// use puts to display sentence
puts("\nThe line entered was:");
puts(sentence);
}
}

I think you must remove character "enter" from stdin. Try:
std::cin >> number;
getchar();

Writing cin.ignore(numeric_limits < streamsize > ::max(), '\n');
in place of std::cin.clear() discards everything in the input stream including the newline.
#include <stdio.h>
#include <iostream>
#include <ios> // for <streamsize>
#include <limits> // for numeric_limits
#define SIZE 80
using namespace std;
int main(void) {
FILE * pFile;
int c; // variable to hold character input by user
char sentence[SIZE]; // create char array
char filename[SIZE]; //create filename array
int i = 0; // initialize counter i
int number;
std::cout << "Give a number. 1 for file. Anything else for standard.";
std::cin >> number;
//std::cin.clear();
cin.ignore(numeric_limits < streamsize > ::max(), '\n');
if (number == 1) {
puts("Enter filename to append: ");
while ((i < SIZE - 1) && (c = getchar()) != '\n') {
filename[i++] = c;
}
filename[i] = '\0';
//fgetc(sentence,80,stdin);
pFile = fopen(filename, "a");
puts("Give a sentence to place in file:");
while ((i < SIZE - 1) && (c = getchar()) != '\n') {
sentence[i++] = c;
}
sentence[i] = '\0';
fputs(sentence, pFile);
fclose(pFile);
do {
c = fgetc(pFile);
} while (c != EOF);
fclose(pFile);
} else {
// prompt user to enter line of text
puts("Enter a line of text:");
// use getchar to read each character
while ((i < SIZE - 1) && (c = getchar()) != '\n') {
sentence[i++] = c;
}
sentence[i] = '\0';
// terminate string
// use puts to display sentence
puts("\nThe line entered was:");
puts(sentence);
}
}

Related

C++: Crashes on trying to write to file

I'm new to C++. The purpose of the program is to give the user an option to open a file, write to it, then read the file that was just written to and display back what is now in the file. When it'll take in the user input, but after hitting enter it will crash. I think it's crashing when it tries to read the file?
#include <stdio.h>
#define SIZE 80
#include <iostream>
int main(void)
{
FILE * pFile;
int c; // variable to hold character input by user
char sentence[SIZE]; // create char array
char filename[SIZE]; //create filename array
char filesentence[SIZE];
int i = 0; // initialize counter i
int number;
std::cout << "Give a number. 1 for file. Anything else for standard.";
std::cin >> number;
getchar();
if(number==1)
{
puts("Enter filename to append: ");
while ((i < SIZE-1) && (c = getchar()) != '\n') {
filename[i++] = c;}
filename[i]= '\0';
//fgetc(sentence,80,stdin);
pFile=fopen(filename,"w+");
puts("Give a sentence to place in file:");
while ((i < SIZE-1) && (c = getchar()) != '\n') {
sentence[i++] = c;}
sentence[i]= '\0';
fputs(sentence,pFile);
i=0;
do {
c = fgetc (pFile);
filesentence[i++] = c;
printf(filesentence);
} while (c != EOF);
fclose (pFile);
}
else
{
// prompt user to enter line of text
puts("Enter a line of text:");
// use getchar to read each character
while ((i < SIZE-1) && (c = getchar()) != '\n') {
sentence[i++] = c;}
sentence[i]= '\0';
// terminate string
// use puts to display sentence
puts("\nThe line entered was:");
puts(sentence);
}
}

C++ peek giving value 'ÿ' (ifstream)

My code first of all:
int GetHighScore(string name)
{
int highScore = 0;
ifstream fin;
char textInFile[50];1
fin.open(name + ".txt", ios::in);
if (fin.fail())
{
// Old piece of code
highScore = 0;
}
else
{
while (fin.good())
{
fin >> textInFile;
for each (char var in textInFile)
{
if (var == '#')
{
char c = fin.peek();
if (c == '1')
{
char score = fin.peek();
highScoreLvl1 = (int)score;
}
else if (c == '2')
{
char score = fin.peek();
highScoreLvl2 = (int)score;
}
else if (c == '3')
{
char score = fin.peek();
highScoreLvl3 = (int)score;
}
}
}
}
//fin >> highScore;
}
// Return the high score found in the file
return highScoreLvl1;
}
It detects the '#', but then c gets assigned the value 'ÿ' when it performs the peek operation. What it should give is the number '1', '2' or '3' (in char form); but it doesn't for some reason, and I can't see why... :/
Here's what the file looks like:
level#12level#22level#32
The first number represents the level, and the second number is the score achieved on that level.
If your file contains the only string 'level#12level#22level#32' then it's read into textInFile in fin >> textInFile operator. When you meet '#' character in the string you're trying to peek character from the file stream but there is nothing to peek, that's why -1 (end of file) is returned.
To fix this you need to take next character from textInFile string, not from the file. Here is example code:
int GetHighScore(string name)
{
int highScore = 0;
ifstream fin;
char textInFile[50];
fin.open(name + ".txt", ios::in);
int highScoreLvl1, highScoreLvl2, highScoreLvl3;
if (fin.fail())
{
// Old piece of code
highScore = 0;
}
else
{
while (fin.good())
{
fin >> textInFile;
bool bPrevIsHash = false;
size_t nLength = strlen(textInFile);
for (size_t i = 0; i + 2 < nLength; ++i)
{
if (textInFile[i] == '#')
{
if (textInFile[i + 1] == '1')
{
highScoreLvl1 = (int)textInFile[i + 2];
}
else if (textInFile[i + 1] == '2')
{
highScoreLvl2 = (int)textInFile[i + 2];
}
else if (textInFile[i + 1] == '3')
{
highScoreLvl3 = (int)textInFile[i + 2];
}
}
}
}
}
// Return the high score found in the file
return highScoreLvl1;
}
And there are several other issues with your code:
You return value of highScoreLvl1 that could be left uninitialized because there can be no '#' in the string. And probably you mean to return max value of highScoreLvl1, highScoreLvl2 or highScoreLvl3.
You're assigning value of char converted to int. In this case you will not get value of 1, 2, etc. You'll get ordinal of ASCII character, e.g. 0x31 (49) for '1', 0x32 (50) for 2, etc. If you need digit value you can do following trick: highScoreLvl1 = textInFile[i + 2] - '0';

How to search for words in a string in a text file?

I am trying to match words from user input with a string from a text file.
When this code runs, it crashes after the file is opened. (marked by ****)
How can I change it to properly match the strings from user input with strings from the text file.
Any help would be appreciated, thank you.
const int Size = 81; // 80 characters for the line + 1 for the '\0'
const int MaxNumberOfWords = 10;
int main() {
char input[81], temp[81], fin[81];
printf("Input a string\n");
fgets(input, 81, stdin);
int len = strlen(input);
char *div;
div = strtok(input, " ");
while (div != NULL) {
printf("%s\n",div);
div = strtok(NULL, " ");
ifstream inStream; // declare an input stream for my use
char theWords[ MaxNumberOfWords][ Size]; // Array to store words from input line
int wordRow = 0; // Row for the current word
char wordToLookup[ Size]; // word to lookup
bool wordWasFound = false; // flag to track whether or not word is found
char c; // stores return character after input
inStream.open( "C:\\Users\\dqiao4\\Desktop\\Dev-Cpp\\dictionaryMax6.txt");
assert( ! inStream.fail() ); // make sure file open was OK
//*****this is where the code crashes
while ( inStream >> theWords[ wordRow]) {
wordRow++;
}
for (int i=0; i<wordRow; i++) {
// See if this word matches
if ( strcmp( div, theWords[ i]) == 0 ){
wordWasFound = true;
break; // quit looking
}
}
}
}
int main() {
char input[81];int i=0,j=0,k=0;
cout<<"Input a string ";
while(i<=80){
input[i]=getch();
cout<<input[i];
if(input[i]=='.')
break;
i++;
}
ifstream File("C:\\User\\New.txt");
string line;
if(File)
{
while(getline(File, line))
{
char buff[1024];
strcpy(buff, line.c_str());
while(j<35){
k=0;
while(k<i){
if(buff[j]==input[k])
{
int j1=j,k1=k;
while(true){
if(buff[j1]==input[k1])
{
if(input[j1]=='.'){
cout<<"match";
return 0;
}
j1++;k1++;
}
else
break;
}
}k++;
}j++;
cout<<endl;
}
}
}
}
#inlude <sstream>
#include <string>
in your source and read the text file in string stream buffer, convert it to string and do
auto pos = file_in_str.find("word_to_find");
That pos is the the starting index of word in file

Write a string to file not equal to string that read from it

Phase 1
example 1: I have string text = "01100001" then I want write to file "a"
example 2: I have string text = "0110000101100010" So I want write to file "ab"
NOTE:I solved phase 1 and result of writing is true.
Phase 2
for example 1:
I want read the file and put it to temp.
So temp = "a" and i convert it to "01100001"
for example 2:
I want read the file and put it to temp.
So temp = "ab" and i convert it to "0110000101100010"
Question
in my code i have below input
string text ="00000110101011100010001011111110011011110101100101110101101111010111111110101011"
"00111011000011100011100000100010111110111110111001100001110001110000101001111010"
"00000101";
I did "phase 1" and I opened the file in a hex editor the writing is true.
But after doing "phase 2" temp != text. Why?
My code
#include <iostream>
#include <sstream>
#include <vector>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
class bitChar{
public:
unsigned char* c;
int shift_count;
string BITS;
bitChar()
{
shift_count = 0;
c = (unsigned char*)calloc(1, sizeof(char));
}
string readByBits(ifstream& inf)
{
string s ="";
while (inf)
{
string strInput;
getline(inf, strInput );
for (int i =0 ; i < strInput.size() ; i++)
{
s += getBits(strInput[i]);
}
}
return s;
}
void setBITS(string X)
{
BITS = X;
}
int insertBits(ofstream& outf)
{
int total = 0 ;
while(BITS.length())
{
if(BITS[0] == '1')
*c |= 1;
*c <<= 1;
++shift_count;
++total;
BITS.erase(0, 1);
if(shift_count == 7 )
{
if(BITS.size()>0)
{
if(BITS[0] == '1')
*c |= 1;
++total;
BITS.erase(0, 1);
}
writeBits(outf);
shift_count = 0;
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
}
if(shift_count > 0)
{
*c <<= (7 - shift_count);
writeBits(outf);
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
outf.close();
return total;
}
string getBits(unsigned char X)
{
stringstream itoa;
for(unsigned s = 7; s > 0 ; s--)
{
itoa << ((X >> s) & 1);
}
itoa << (X&1) ;
return itoa.str();
}
void writeBits(ofstream& outf)
{
outf << *c;
}
~bitChar()
{
if(c)
free(c);
}
};
int main()
{
ofstream outf("ssSample.dat",ios::binary);
string text ="00000110101011100010001011111110011011110101100101110101101111010111111110101011"
"00111011000011100011100000100010111110111110111001100001110001110000101001111010"
"00000101";
cout<< text<<endl;
//write to file
bitChar bchar;
bchar.setBITS(text);
bchar.insertBits(outf);
outf.close();
ifstream inf("ssSample.dat" ,ios::binary);
//READ FROM FILE
string temp=bchar.readByBits(inf);
cout << endl;
cout << temp << endl;
return 0;
}
You have a LF Line Feed character. This is the character that is getting omitted.
0000 1010
This may be unrelated, but Windows requires a CR and LF for a new line. This code may act differently in Windows vs. Unix.
Read one byte at a time.
string readByBits(ifstream& inf)
{
string s ="";
char buffer[1];
while (inf.read (buffer, 1))
{
// string strInput;
//getline(inf, strInput );
//for (int i =0 ; i < strInput.size() ; i++)
//{
s += getBits(*buffer);
//}
}
return s;
}
Program output:
000001101010111000100010111111100110111101011001011101011011110101111111101010110011101100001110001110000010001011111011111011100110000111000111000010100111101000000101
000001101010111000100010111111100110111101011001011101011011110101111111101010110011101100001110001110000010001011111011111011100110000111000111000010100111101000000101
One problem with your approach is that your text must be a multiple of 8 bits to work. Otherwise, even if everything is correct, that last character will be read from the file and converted to 8 binary digits in the string adding trailing zeros.
Two problems I quickly identified (but I assume there are more)
Your input is not a multiple of 8-bits
By using getLine you're reading until you meet a delimiting character and thus spoiling your result since you're not dealing with a text-based file

reading input from keyboard

I am required to read from an keyboard(stdin), the following text. Pl note that it will be entered by user from keyboard in this format only.
#the total size of physical memory (units are B, KB, MB, GB)
512MB 2 #the following are memory allocations
{
abc = alloc(1KB);
{
y_ = alloc(128MB);
x1= alloc(128MB);
y_ = alloc(32MB);
for (i = 0; i < 256; i++) abc[i] =alloc(512kB);
x1 = alloc(32MB); x2 = alloc(32MB); x3 = alloc(32MB);
x1.next = x2, x2.next = x3, x3.next = x1;
}
abc = alloc(256MB);
}
So basically let me break it down.
a line beginning with # sign is considered as comment and is ignored.
the first two allocations are physical memory size and number of generations.
a global bracket will be opened.
and it may be followed by a line called
abc = alloc(1KB);
where abc is the object name, 1KB is the memory size allocated.
x1.next = x2, here x1 points to x2.
for (i = 0; i < 256; i++) abc[i] =alloc(512kB);
the for loop os entered in this format and it can have a same line command or can have nested for loops.
I have the following code that takes care of this somewhat. I want to know improve on it. Please do help.
And my code is this:
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <limits>
#include <stdio.h>
#include <sstream>
using namespace std;
using std::stringstream;
string pMem,sGen, comment,val,input,input_for,id_size,id,init_str1, init_str2, inc_str, id_dummy,s_out,sss, id_dummy1;
int gen=0, pMem_int=0,i=0, gBrckt =0,cBrckt=0, oBrckt=0, id_size_int,v1,v2, for_oBrckt=0,for_cBrckt=0,y=0, y1=0, g=0;
unsigned long pMem_ulong =0, id_size_ulong;
char t[20], m[256], init1[10],init2[10],inc[10];
unsigned pos_start, pos,pos_strt=0,pos_end=0;
string extract(string pMem_extract);
unsigned long toByte(int pMem_int_func, string val);
void commentIgnore(string& input);
void func_insert();
void func_insert_for();
stringstream out;
void commentIgnore_for(string& input_for);
int main()
{
/* Reading the input main memory and num of generations */
/* Ignoring comment line */
cin >> pMem;
if(pMem == "#") {
cin.clear();
pMem.clear();
getline(cin,comment);
cin >> pMem;
}
if(pMem == "#") {
cin.clear();
pMem.clear();
getline(cin,comment);
cin >> pMem;
}
if(pMem == "#") {
cin.clear();
pMem.clear();
getline(cin,comment);
cin >> pMem;
}
/* Reading input generations */
cin>> sGen;
if(sGen == "#") {
cin.clear();
sGen.clear();
getline(cin,comment);
cin >> sGen;
}
if(sGen == "#") {
cin.clear();
sGen.clear();
getline(cin,comment);
cin >> sGen;
}
if(sGen == "#") {
cin.clear();
sGen.clear();
getline(cin,comment);
cin >> sGen;
}
/* Convert sGen and physical memory to int and report error if not a number */
gen = atoi(sGen.c_str());
if(gen ==0) {
cerr << "Generation must be a number"<<endl;
exit(0);
}
pMem_int = atoi(pMem.c_str());
// cout<< gen<<" "<<pMem_int<<endl;
/* Now that the number from pMem is removed, get its unit B,MB,KB */
extract(pMem); /* returns val(string) */
/* convert the given physical memory to Byte. input: pMem_int*/
toByte(pMem_int, val); /* return(pMem_ulong)*/
// move pMem_ulond to another location to keep address intact
/* read rest of the inputs */
/* Ignore comment lines before the global bracket */
cin >> input;
if(input == "#"){
cin.clear();
input.clear();
getline(cin,comment);
cin >> input;
}
if(input == "#"){
cin.clear();
input.clear();
getline(cin,comment);
cin >> input;
}
if(input == "#"){
cin.clear();
input.clear();
getline(cin,comment);
cin >> input;
}
if(input.compare("{") ==0)
gBrckt=1;
else {
cerr<< "Syntax error\n";
exit(0);
}
/* Clearing the input stream for next input */
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.clear();
input.clear();
//cout<<"input: "<<input<<endl;
while( getline(cin,input)) {
if(input == "CTRL-D")
break;
commentIgnore(input);
//cout<<"inputloop: "<<input<<endl;
/* If input = '{' or '}'*/
if(input.compare("{") ==0)
oBrckt = oBrckt + 1;
if (input.compare("}") ==0)
cBrckt = cBrckt + 1;
if (((input.find("alloc"))!= string::npos) && (input.find("alloc") < input.find("for"))) {
func_insert();
//call the allocate function here with name: id, size: id_size_ulong
}
if ((input.find("for")) != string::npos) {
sscanf(input.c_str(), "for (%s = %d; %s < %d; %[^)])", init1, &v1, init2, &v2, inc);
init_str1 = init1, init_str2 = init2, inc_str = inc;
cout<<init1<<" ="<< v1<<" "<<init_str1<<" < " << v2<< " "<< inc_str<<endl;
cout << input <<endl;
if(init_str1 != init_str2) {
cerr << "Error!\n";
exit(0);
}
if ((input.find("alloc"))!= string::npos) {
// unsigned pos = (input.find("alloc"));
if((input.find(";")) != string::npos) {
pos_start = (input.find(")")+1);
string alloc_substr = input.substr(pos_start);
cout<<"Substring alloc: "<< alloc_substr<<endl;
func_insert();
//call the allocate function here with name: id, size: id_size_ulong
}
else {
cerr << "ERROR: SYNTAX\n";
exit(0);
}
}
// cin.ignore();
while(getline(cin,input_for)) {
commentIgnore_for(input_for);
if ((input_for.find("{") != string::npos)) {
pos = input_for.find("{");
for_oBrckt = for_oBrckt+1;
string for_brckt = input_for.substr(pos,pos);
cout<< "Found: " << for_oBrckt<<endl;
}
if ((input_for.find("}") != string::npos)) {
pos = input_for.find("}");
for_cBrckt = for_cBrckt+1;
string for_brckt = input_for.substr(pos,pos);
cout<< "Found: " << for_cBrckt<<endl;
}
if (((input_for.find("alloc"))!= string::npos) && (input_for.find("alloc") < input_for.find("for"))) {
func_insert_for();
//call the allocate function here with name: id, size: id_size_ulong
}
if(for_oBrckt == for_cBrckt)
break;
}
cout<<"out of break"<<endl;
}
if (((input.find(".next"))!= string::npos) && (input.find(".next") < input.find("for"))) {
func_insert();
//call the allocate function here with name: id, size: id_size_ulong
}
if(((cBrckt-oBrckt)) == gBrckt)
break;
}
}
/*---------------------- Function definitions --------------------------------*/
/* Function to extract the string part of physical memory */
string extract(string pMem_extract) {
i=0;
const char *p = pMem_extract.c_str();
for(i=0; i<=(pMem_extract.length()); i++) {
if (*p=='0'|| *p=='1'|| *p=='2'|| *p=='3'|| *p =='4'|| *p=='5'|| *p=='6'|| *p=='7'|| *p=='8'|| *p=='9')
*p++;
else {
val = pMem_extract.substr(i);
return(val);
}
}
}
/* Convert the physical memory to bytes. return(pMem_ulong);*/
unsigned long toByte(int pMem_int_func, string val)
{
if (val == "KB")
pMem_ulong = (unsigned long) pMem_int_func * 1024;
else if (val == "B")
pMem_ulong = (unsigned long) pMem_int_func;
else if (val == "GB")
pMem_ulong = (unsigned long) pMem_int_func * 1073741824;
else if (val == "MB")
pMem_ulong = (unsigned long) pMem_int_func * 1048576;
else {
cerr<<"Missing the value in memory, B, KB, MB, GB\n";
exit(0);
}
return(pMem_ulong);
}
/*Ignoring comment line*/
void commentIgnore(string& input)
{
unsigned found = input.find('#');
if (found!=std::string::npos)
input= input.erase(found);
else
return;
return;
}
void func_insert() {
sscanf(input.c_str(), "%s = alloc(%[^)]);", t, m);
id =t;
id_size =m;
cout<<"Tag: "<<id <<" Memory: "<<id_size<<endl;
extract(id_size); /* Separates B,MB,KB and GB of input, returns val*/
id_size_int = atoi(id_size.c_str());
/* Convert object size to B */
toByte(id_size_int, val); /* return(pMem_ulong) */
id_size_ulong = pMem_ulong;
}
void func_insert_for() {
sscanf(input_for.c_str(), "%s = alloc(%[^)]);", t, m);
id =t;
id_size =m;
if(!((id.find("[")) && (id.find("]")) != string::npos)) {
cout<<"Tag: "<<id <<" Memory: "<<id_size<<endl;
extract(id_size); /* Separates B,MB,KB and GB of input, returns val*/
id_size_int = atoi(id_size.c_str());
/* Convert object size to B */
toByte(id_size_int, val); /* return(pMem_ulong) */
id_size_ulong = pMem_ulong;
// allocate here
return;
}
else {
if(inc_str.find("++"))
y1 =1;
if(inc_str.find("="))
{
sss = inc_str.substr(inc_str.find("+") +1);
y1 = atoi(sss.c_str());
cout<<"y1:"<<y1<<endl;
}
pos_strt = id.find("[");
pos_end = id.find("]") -1;
cout<<"Positions start and ebd: " << pos_strt<<pos_end<<endl;
id_dummy = id.substr(0,pos_strt);
id = id_dummy;
cout<<"Tag: "<<id_dummy <<" Memory: "<<id_size<<endl;
extract(id_size); /* Separates B,MB,KB and GB of input, returns val*/
id_size_int = atoi(id_size.c_str());
/* Convert object size to B */
toByte(id_size_int, val); /* return(pMem_ulong) */
id_size_ulong = pMem_ulong;
//allocate here
cout<<"v1: " << v1 << " " << v2<<endl;
// g = 0;
for(y = v1; y < v2; y= y+y1) {
// allocate here
}
}
return;
}
void commentIgnore_for(string& input_for)
{
unsigned found = input_for.find('#');
if (found!=std::string::npos)
input_for= input_for.erase(found);
else
return;
return;
}
Also i am required to make it whitespace compatible. What it means is that input can be entered in one line as well. like two allocations in one line. Which i have not been able to taken care. I need help with that.
My suggestion would be that you write a proper tokenizer - a piece of code that understands what belongs together (such as "words"), and where to split (e.g. "(, ), {, }"). The tokenizer would return an enum, something like this:
enum Token {
Token_Unknown, // Error indiciation.
Token_LeftParen,
Token_RightParen,
Token_LeftBracket,
Token_RightBracket,
Token_Comma,
Token_Semicolon,
Token_Equal,
Token_Word, // Sequence of alphanumerics
};
Once you have a token, you need to understand what that token is. It may make sense to have a table of "known" tokens (aka "keywords"), such as "mem", "alloc", "for", and so on. If something isn't a keyword, it's the name of a symbol, such as a variable. You store those in a table, so that you can refer to them later.
You will have to use some sort of stack of where you are, so you can get back to where you came from when you finish.
Writing a generic parser isn't terribly hard, and you will most likely end up with a lot less code than your current code in doing so.
Certainly, you'd be able to get rid of all the:
if(input == "#"){
cin.clear();
input.clear();
getline(cin,comment);
cin >> input;
}
Just let the parser check if there is a '#' as the input, and skip over to the end of the line (completing the current token if you have one, if not, just keep going).
IIUC, the input is not line oriented, so the usual rule of
using std::getline may not apply. My own approach would be:
Insert a filtering streambuf to removed the comments.
Use some sort of regular expression based lexer (e.g. flex)
to break the input up into tokens.
Define the grammar; I'd use bison once I'd gotten this far,
in order to generate the code to parse the grammar, but a simple
recursive descent parser shouldn't be too hard to write.
You don't say what you must do with the information once you
have parsed it, so it's hard to give more precise advice.