I have created a program in c++ to remove the commments of a c/c++ file and put a comment-removed version in another file. However after hours of debugging it is still not working. Help please!
"input" is a string that has the folder location of the c/c++ files.
"files" is a vector with all the file names in the folder but not their locations.
I use "input" and "files" to get the file name and location.
for (unsigned int i = 0; i < files.size();i++ ){//for loop start
iteratora++;
string filename1 = input;
filename1.append("\\");
filename1.append(files[iteratora + 2]);
cout << "\n" << filename1 << ".\n";
cout << "Iterator: " << iteratora << ".\n";
programFile.clear();
ifstream afile (filename1);//(filename1);
fstream temp ("temp/temp.txt",std::ofstream::out | std::ofstream::trunc);
string line;//variable for holding the characters in one line
remove_comments(afile,temp);
if (temp.is_open())
{
while ( getline (temp,line) )
{
//cout << line << '\n';
if (line != ""){
cout << line;
programFile.push_back(line);
line = "";
}
}
temp.close();
}
temp.clear();
if (showVerbose == true){
print_vector(programFile);//used to know what is in the file
}
}
remove comments function
void remove_comments ( ifstream& Source , fstream& Target)
{
string line;
bool flag = false;
while ( ! Source.eof() ) // This loop is to get assure that the whole input file is read.
{
getline(Source, line); // To read line by line.
if ( flag )
{ if ( line.find("*/") < line.length() )
flag = false;
line.erase(0,line.find("*/") + 2);
}
if ( line.find("/*") < line.length() ) // searching for " /* " to eliminat it and all its content.
flag = true;
if ( ! flag )
{
for (int i = 0; i < line.length(); i++ )
{
if(i<line.length())
if ( ( line.at(i) == '/' ) && ( line.at(i + 1 ) == '/' ) ) // searching for " // " to eliminate all its content.
break;
else
Target << line[i]; // To copy lines in the output file.
}
Target<<endl;
}
}
Source.close(); // to close the opened files.
Target.close();
}
Thanks!
find method of string returns std::string::npos on unsuccessful search , so you should write this line
if(line.find("/*") < line.length())
as below:
if(line.find("/*") != std::string::npos)
Make similar changes and try.
Here is another solution.
It opens file.txt and loads the entire file into a string. Then it removes the
comments and writes the new data in string back into file.txt.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void) {
string source;
ifstream readFile("file.txt");
getline(readFile, source, '\0');
readFile.close();
cout<<"\n---b e f o r e -----------------------------------\n\n";
cout << source;
while(source.find("/*") != string::npos) {
size_t Beg = source.find("/*");
source.erase(Beg, (source.find("*/", Beg) - Beg)+2);
}
while(source.find("//") != string::npos) {
size_t Beg = source.find("//");
source.erase(Beg, source.find("\n", Beg) - Beg);
}
ofstream writefile("file.txt");
writefile <<source;
writefile.close();
cout<<"\n\n-- a f t e r -------------------------------------------\n\n";
cout << source;
cout<<"\n---------------------------------------------\n\n";
cout<<"\n\n";
return 0;
}
Related
This file is not opening for a reason which I don't know really, any insight?
#include <iostream>
#include <string>
#include <algorithm>
#include <fstream>
#include <cctype>
using namespace std;
.
.
.
.
.
void MinHeap::TopKFrequentWord(string fileName, int k)
{
MinHeap mh;
Trie T;
string word;
string line;
ifstream inFile(fileName);
for (int i = 0; i < 22; i++)
{
if (i >= 10)
{
fileName = "C:\\Users\\Kareem's Laptop\\Desktop\\Reuters-21578\\reut2-0" + to_string(i) + ".sgm";
}
else if (i <= 9)
{
fileName = "C:\\Users\\Kareem's Laptop\\Desktop\\Reuters-21578\\reut2-00" + to_string(i) + ".sgm";
}
if (!inFile)
{
cout << fileName << " did not open." << endl;
exit(1);
}
bool found = true;
while (inFile >> line)
{
size_t pos = line.find("<BODY>");
if (pos != string::npos)
{
if (found)
{
word = line.substr(pos + 6);
found = true;
TrieNode* TN = T.search(word);
if (!TN)
{
TN = T.insert(word);
}
else
{
TN->frequency++;
}
mh.insert(TN, word);
}
}
}
mh.Display();
cout << '\n';
inFile.close();
}
}
int main()
{
MinHeap foo;
string fileName;
foo.TopKFrequentWord(fileName, 10);
return 0;
}
I have to open 21 files in a loop, read them all and print out the top 10 word count for all of those words.
Unable to use vector due to instructions. I apologize if similarities are obvious.
I tried putting all files in an array but it still didn't work. No errors just not opening (getting exit(1) command).
You are opening the file before the loop. Since you are updating the filename variable inside the loop, I suppose you want to open it each time you pass through the loop.
Move the line :
ifstream inFile(fileName);
to one line before the test:
if (!inFile)
Also, the place where you code ifstream inFile(fileName); you have an empty string in fileName (You didn't initialize the variable passed as argument in main).
Also, you are passing a int k parameter to the function but never uses it there.
I have a program that reverses the letters in a sentence but keeps the words in the same order. I need to change the code from an iostream library to an fstream library where the user inputs a sentence into an input file("input.txt") and the program outputs the reverse into an output text file.
example of input:
This problem is too easy for me. I am an amazing programmer. Do you agree?
Example of output:
sihT melborp si oot ysae rof em. I ma na gnizama remmargorp. oD uoy eerga?
The code I already have:
int main()
{
int i=0, j=0, k=0, l=0;
char x[14] = "I LOVE CODING";
char y[14] = {'\0'};
for(i=0; i<=14; i++) {
if(x[i]==' ' || x[i]=='\0') {
for(j=i-1; j>=l; j--)
y[k++] = x[j];
y[k++] = ' ';
l=i+1;
}
}
cout << y;
return 0;
}
I would use std::string to store the string, and benefit from std::vector and const_iterator to make better use of C++ features:
#include <string>
#include <vector>
int main()
{
std::string s("This problem is too easy for me. I am an amazing programmer. Do you agree?");
const char delim = ' ';
std::vector<std::string> v;
std::string tmp;
for(std::string::const_iterator i = s.begin(); i <= s.end(); ++i)
{
if(*i != delim && i != s.end())
{
tmp += *i;
}else
{
v.push_back(tmp);
tmp = "";
}
}
for(std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it)
{
std::string str = *it,b;
for(int i=str.size()-1;i>=0;i--)
b+=str[i];
std::cout << b << " ";
}
std::cout << std::endl;
}
Output:
sihT melborp si oot ysae rof .em I ma na gnizama .remmargorp oD uoy ?eerga
The code that you submitted looks much more like something from C rather than from C++. Not sure if you are familiar std::string and function calls. As the code you wrote is pretty sophisticated, I will assume that you are.
Here is an example of how to use fstream. I almost always you getline for the input because I find that it gets me into fewer problems.
I then almost always use stringstream for parsing the line because it neatly splits the lines at each space.
Finally, I try to figure out a while() or do{}while(); loop that will trigger off of the input from the getline() call.
Note that if the word ends in a punctuation character, to keep the punctuation at the end, the reverse_word() function has to look for non-alpha characters at the end and then save that aside. This could be done by only reversing runs of alphas.
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
///////////////////
/// return true if ch is alpha
/// return false for digits, punctuation, and all else
bool is_letter(char ch){
if((ch >= 'A' && ch <= 'Z') ||
(ch >= 'a' && ch <= 'z')) {
return true;
} else {
return false;
}
}
////////
// Only reverse the letter portion of each word
//
std::string reverse_word(std::string str)
{
std::string output_str; // Probably have to create a copy for output
output_str.reserve(str.length()); // reserve size equal to input string
// iterate through each letter of the string, backwards,
// and copy the letters to the new string
char save_non_alpha = 0;
for (auto it = str.rbegin(); it != str.rend(); it++) {
/// If the last character is punctuation, then save it to paste on the end
if(it == str.rbegin() && !is_letter(*it)) {
save_non_alpha = *it;
} else {
output_str += *it;
}
}
if(save_non_alpha != 0) {
output_str += save_non_alpha;
}
return output_str; // send string back to caller
}
int main()
{
std::string input_file_name{"input.txt"};
std::string output_file_name{"output.txt"};
std::string input_line;
std::ifstream inFile;
std::ofstream outFile;
inFile.open(input_file_name, std::ios::in);
outFile.open(output_file_name, std::ios::out);
// if the file open failed, then exit
if (!inFile.is_open() || !outFile.is_open()) {
std::cout << "File " << input_file_name
<< " or file " << output_file_name
<< " could not be opened...exiting\n";
return -1;
}
while (std::getline(inFile, input_line)) {
std::string word;
std::string sentence;
std::stringstream stream(input_line);
// I just like stringstreams. Process the input_line
// as a series of words from stringstream. Stringstream
// will split on whitespace. Punctuation will be reversed with the
// word that it is touching
while (stream >> word) {
if(!sentence.empty()) // add a space before all but the first word
sentence += " ";
word = reverse_word(word);
sentence += word;
}
outFile << sentence << std::endl;
}
inFile.close();
outFile.close();
return 0;
}
So, I'm trying to read a text file into a two dimensional array in C++.
The problem is that the number of words in each line is not always the same, a line can contain up to 11 words.
For example, the input file could contain:
ZeroZero ZeroOne ZeroTwo ZeroThree
OneZero OneOne
TwoZero TwoOne TwoTwo
ThreeZero
FourZero FourOne
Therefore, array[2][1] should contain "TwoOne", array[1][1] should contain "OneOne", etc.
I don't know how to make my program increase the row number every line. what I have obviously is not working:
string myArray[50][11]; //The max, # of lines is 50
ifstream file(FileName);
if (file.fail())
{
cout << "The file could not be opened\n";
exit(1);
}
else if (file.is_open())
{
for (int i = 0; i < 50; ++i)
{
for (int j = 0; j < 11; ++j)
{
file >> myArray[i][j];
}
}
}
You should use a vector<vector<string>> to store the data as you don't know in advance how much data will be there to read.
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
const string FileName = "a.txt";
ifstream fin ( FileName );
if ( fin.fail() )
{
cout << "The file could not be opened\n";
exit ( 1 );
}
else if ( fin.is_open() )
{
vector<vector<string>> myArray;
string line;
while ( getline ( fin, line ) )
{
myArray.push_back ( vector<string>() );
stringstream ss ( line );
string word;
while ( ss >> word )
{
myArray.back().push_back ( word );
}
}
for ( size_t i = 0; i < myArray.size(); i++ )
{
for ( size_t j = 0; j < myArray[i].size(); j++ )
{
cout << myArray[i][j] << " ";
}
cout << endl;
}
}
}
I want to start of by saying that I am still learning and some might think that my code looks bad, but here it goes.
So I have this text file we can call example.txt.
A line in example.txt can look like this:
randomstuffhereitem=1234randomstuffhere
I want my program to take in the numbers that are next to the item= and I have started a bit on it using the following code.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string word;
int main()
{
ifstream readFile("example.txt", ios::app);
ofstream outfile("Found_Words.txt", ios::app);
bool found = false;
long int price;
cout << "Insert a number" << endl;
cout << "number:";
cin >> number;
system("cls");
outfile << "Here I start:";
while( readFile >> word )
{
if(word == "item=")
Here is the problem; first of all it only searchs for "item=" but to find it, it cannot be included with other letters. It has to be a standalone word.
It wont find:
helloitem=hello
It will find:
hello item= hello
It has to be separated with spaces which is also a problem.
Secondly I want to find numbers next to the item=. Like I want it to be able to find item=1234 and please note that 1234 can be any number like 6723.
And I dont want it to find what comes after the number, so when the number stops, it wont take in anymore data. Like item=1234hello has to be item=1234
{
cout <<"The word has been found." << endl;
outfile << word << "/" << number;
//outfile.close();
if(word == "item=")
{
outfile << ",";
}
found = true;
}
}
outfile << "finishes here" ;
outfile.close();
if( found = false){
cout <<"Not found" << endl;
}
system ("pause");
}
You can use a code like this:
bool get_price(std::string s, std::string & rest, int & value)
{
int pos = 0; //To track a position inside a string
do //loop through "item" entries in the string
{
pos = s.find("item", pos); //Get an index in the string where "item" is found
if (pos == s.npos) //No "item" in string
break;
pos += 4; //"item" length
while (pos < s.length() && s[pos] == ' ') ++pos; //Skip spaces between "item" and "="
if (pos < s.length() && s[pos] == '=') //Next char is "="
{
++pos; //Move forward one char, the "="
while (pos < s.length() && s[pos] == ' ') ++pos; //Skip spaces between "=" and digits
const char * value_place = s.c_str() + pos; //The number
if (*value_place < '0' || *value_place > '9') continue; //we have no number after =
value = atoi(value_place); //Convert as much digits to a number as possible
while (pos < s.length() && s[pos] >= '0' && s[pos] <= '9') ++pos; //skip number
rest = s.substr(pos); //Return the remainder of the string
return true; //The string matches
}
} while (1);
return false; //We did not find a match
}
Note that you should also change the way you read strings from file. You can either read to newline (std::getline) or to the end of stream, like mentioned here: stackoverflow question
Hey, sorry if this is asked a lot but I have no idea what the problem here is.
In the C++ code below, I'm reading from a user defined input file and generating output. I've been writing it piece by piece and putting it together, compiling, testing, etc as I go to work out the bugs. This is a learning experience for me, first self-directed program I guess...
Anyways, when I run the code, the command prompt prints ONE line and goes unresponsive. I would say it has been caught in some kind of loop, but I believe that's impossible.
I think it might have something to do with the array I'm trying to declare, I wanted to make a dynamic string array but I found out that's difficult...
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <string>
using namespace std;
int wordCount(string line)
{
int fpos, fpos2;
int count = 0;
fpos = line.find_first_not_of(' ');
line.erase(0, fpos);
while(line.size() > 0)
{
fpos = line.find_first_of(' ');
if(line.at(0) == '"')
{
line.erase(0, 1);
for(int i = 0; i <line.size(); i++)
if(line.at(i) == '"' && line.at(i-1) != '\\')
{
fpos2 = i;
break;
}
line.erase(0, fpos2 + 2);
}
else
line.erase(0, fpos + 1);
count++;
}
return count;
}
int main()
{
//Current line; Input file; Output file;
string currentline, fileName, outFileName;
ifstream fin;
ofstream fout;
cout << "Enter input file name: ";
getline(cin, fileName);
cout << "Enter output file name: ";
getline(cin, outFileName);
fin.open(fileName.c_str());
if (!fin.good()) throw "I/O error";
fout.open(outFileName.c_str());
if (!fout.good()) throw "I/O error";
getline(fin, currentline);
while (!currentline.empty())
{
int pos, pos1;
pos = currentline.find("//");
string postScript = currentline.substr(pos+2,-1);
pos = currentline.find_first_of(';');
string xline = currentline.substr(0,pos+1);
cout << xline << endl;
int size = wordCount(xline);
string *words;
words = (string *) malloc (size*sizeof(string));
words = new string[size];
pos = xline.find_first_not_of(' ');
xline.erase(0, pos);
for ( int i = 0; i < size; i++ )
{
pos = xline.find_first_of(' ');
if ( xline.at(0) == '"' )
{
xline.erase(0, 1);
for(int a = 0; a < xline.size(); a++) //This for loop finds the end of a quoted statement within the line.
if ( xline.at(a) == '"' && xline.at(a-1) != '\\' )
{
pos = a;
break;
}
words[i] = xline.substr(0,pos);
xline.erase(0,pos + 2);
}
else
{
words[i] = xline.substr(0,pos);
xline.erase(0,pos + 1);
}
cout << words[i] << endl;
}
cout << xline << endl << endl;
getline(fin, currentline);
}
return 0;
}
I would suggest you commenting out bits of code until it starts to work the way you expect (Usually the problematic bit will become obvious this way.) Once you figure out what is wrong you can ask a more specific question on StackOverflow.
You should use a debugger to investigate the program behavior.
To avoid single stepping the whole program, you can set breakpoints where you expect to passs the sequence. When a breakpoint is not hit you can use single stepping from the previous point. Additionally you can look at variables content.
It never finds the end quote:
if ( xline.at(a) == '"' && xline.at(a-1) != '\\' )
{
pos = a;
break;
}
Try this instead:
if (xline.at(a) == '"')
{
pos = a;
break;
}
You only need to escape " if its contained in a string literal, e.g. "There's a \" in this literal"