Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am attempting to grab ID's from an text file with HTML in it. The ID's are being extracted from URL's in the HTML so I'm looping through the file to find the correct line and then using substrings obtain the correct information. There are two different types of ID so I have two different functions.
The second one (getYearId) works fine, but the first one causes the code to abort on the part that is currently commented out. As you can see, I've tried to output the value of first1 only to find that it's output is alue=", which is part of what I'd assume first was supposed to equal. What am I doing wrong?
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;
void getSyllabiId() {
string line;
ifstream myfile("syllabi.txt");
if (myfile.is_open()) {
while (getline(myfile, line)) {
if (line.find("View Assignments") != string::npos) {
string startDel = "syllabusid";
string endDel = "View";
unsigned int first1 = line.find(startDel);
unsigned int last1 = line.find(endDel);
cout << first1 + "\n";
//string syllabusID = line.substr(first1, last1 - first1);
//syllabusID = syllabusID.substr(startDel.size());
// cout << syllabusID + "\n";
}
}
myfile.close();
}
else cout << "Unable to open file.";
}
void getYearId() {
string line;
ifstream myfile("syllabi.txt");
if (myfile.is_open()) {
while (getline(myfile, line)) {
if (line.find("2014-2015</option>") != string::npos) {
string startDel = "value=\"";
string endDel = "\" selected";
unsigned int first = line.find(startDel);
unsigned int last = line.find(endDel);
string yearID = line.substr(first, last - first);
yearID = yearID.substr(startDel.size());
cout << yearID + "\n";
}
}
myfile.close();
}
else cout << "Unable to open file";
}
int main () {
getYearId();
getSyllabiId();
string x;
cin >> x;
return 0;
}
The problem was I never checked to see if first1 and last1 had values, so obviously in one (or several instances) one of them didn't causing the code to abort.
Related
I cannot figure out how to list out the lines that contain a specified word. I am provided a .txt file that contains lines of text.
So far I have come this far, but my code is outputting the amount of lines there are. Currently this is the solution that made sense in my head:
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
void searchFile(istream& file, string& word) {
string line;
int lineCount = 0;
while(getline(file, line)) {
lineCount++;
if (line.find(word)) {
cout << lineCount;
}
}
}
int main() {
ifstream infile("words.txt");
string word = "test";
searchFile(infile, word);
}
However, this code simply doesn't get the results I expect.
The output should just simply state which lines have the specified word on them.
So, to sum up the solution from the comments. It is just about the std::string's find member function. It doesn't return anything compatible with a boolean, it either return an index if found, or std::string::npos if not found, which is a special constant.
So calling it with traditional way if (line.find(word)) is wrong, but instead, it should be checked this way:
if (line.find(word) != std::string::npos) {
std::cout << "Found the string at line: " << lineCount << "\n";
} else {
// String not found (of course this else block could be omitted)
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
As the title suggests I am trying to find a specific word inside a file, and then deleting the line including it, but what I do here destroys the content of the file:
cin>>ID; //id of the line we want to delete
ifstream read;
read.open("infos.txt");
ofstream write;
write.open("infos.txt");
while (read >> name >> surname >> id) {
if (ID != id) {
write << name << " " << surname << " " << id << endl;
}
else write << " ";
}
read.close();
write.close();
Both of your files have same name. Calling basic_ofstream::open destroys content of a file if it already exists. In your case you destroyed data in input file before doing anything. Use different name and later rename. I assume line in input is ended with "\n" so we can use getline(). Then we need to tell if word is present in line and for that there is this function. std::string:npos is returned if line doesn't contain word.
#include <cstdio> // include for std::rename
#include <fstream>
#include <string>
void removeID() {
std::string ID;
cin >> ID; //id of the line we want to delete
ifstream read("infos.txt");
ofstream write("tmp.txt");
if (read.is_open()) {
std::string line;
while (getline(read, line)) {
if (line.find(ID) != std::string::npos)
write << line;
}
} else {
std::cerr << "Error: coudn't open file\n";
/* additional handle */
}
read.close();
write.close();
std::remove("infos.txt");
std::rename("tmp.txt", "infos.txt");
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
My task is to search for a string in .c file and modify it using c++ code. Iam done till searching for the string but modifying it is giving an error. It gives the same error if i copy the contents of c file to a text file and try to modify it. So iam sure something is wrong with my code. Please help as iam a beginner. Thanks in advance.
My code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string s1, s2;
ifstream test("test.csv");
while (test.eof()==0) //test.eof() returns 0 if the file end is not reached
{
getline(test, s1, ','); //reads an entire line(row) till ',' to s1
getline(test, s2, '\n');
cout << s1 + "= " +s2 << endl;
fstream fileInput;
int offset;
string line;
string search=s1;
fileInput.open("IO_CAN_0_User.c");
if(fileInput.is_open()) {
while(!fileInput.eof()) {
getline(fileInput, line);
if ((offset = line.find(search, 0)) != string::npos) {
cout << "found: " << search << endl;
string str;
str=search;
str.replace(str.begin()+25,str.begin()+31,"=s2 //");
break;
}
}
//cout << "string not found" << endl;
fileInput.close();
}
else cout << "Unable to open file.";
if(test.eof()!=0)
cout<<"end of file reached"<<endl;
getchar();
return 0;
}
}
The error your are facing is not clear, but I can see one big issue, your running replace on an empty string.
Your code:
string str;
search=str;
str.replace(str.begin()+25,str.begin()+31,"=s2 //");
You create str (by default initialized as empty string), assign it to search (therefore this string gets empty) and then you call replace trying to change from char 25 to 31, which are not there since the str is empty.
Update
Probably you need to fix the replace, but then you cannot expect the file to change: the string you are modifying is in memory, not a piece of your file.
Therefore I would change the code (using yours as much as possible):
* Adding output file
* Fixing the replace
* Saving every line of the input file (replacing if need) on the output
fileInput.open("IO_CAN_0_User.c");
ofstream fileOutput;
fileOutput.open("output.c");
if(fileInput.is_open() && fileOutput.is_open() ) {
while(!fileInput.eof()) {
getline(fileInput, line);
if ((offset = line.find(search, 0)) != string::npos) {
cout << "found: " << search << endl;
line.replace( offset, offset+search.size(), s2 );
}
fileOutput << line << '\n';
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
writing a very basic lexical analyzer in standard
C++ (std usage is allowed) that reads a text file
as input and writes all the "tokens" to an output
file line by line
● All items that are separated by white space are
tokens
● White space includes
● Space(s)
● Newlines
● Tabs
Input file having this
if (x > 50)
x=0
Output file should be like this
if
(
x
>
50
)
x
=
0
Edit 3
Ok so im almost there i have made an input file that takes whatever is written in it and then tokenizes it and shows on the screen. an output file is generated bt when it shows this output Output tokens 0033F8C8 i thinks its the array address. now all i need to do is store the output being shown on the screen should go into the output text file and on the screen it should print see your output file your inputs are tokenized.
code edit 3
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
using std::ifstream;
#include <cstring>
using namespace std;
const int MAX_CHARS_PER_LINE = 512;
const int MAX_TOKENS_PER_LINE = 20;
const char* const DELIMITER = " ";
int main()
{
// create a file-reading object
ifstream infile;
infile.open("input.txt"); // open a file
if (!infile.good())
return 1; // exit if file not found
ofstream outfile;
outfile.open("output.txt");
if (!outfile)
{
cout << "error opening fiLe";
}
// read each line of the file
while (!infile.eof())
{
// read an entire line into memory
char buf[MAX_CHARS_PER_LINE];
infile.getline(buf, MAX_CHARS_PER_LINE);
// parse the line into blank-delimited tokens
int n = 0; // a for-loop index
// array to store memory addresses of the tokens in buf
const char* token[MAX_TOKENS_PER_LINE] = {}; // initialize to 0
// parse the line
token[0] = strtok(buf, DELIMITER); // first token
if (token[0]) // zero if line is blank
{
for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
{
token[n] = strtok(0, DELIMITER); // subsequent tokens
if (!token[n]) break; // no more tokens
}
}
// process (print) the tokens
for (int i = 0; i < n; i++) // n = #of tokens
cout << "Token[" << i << "] = " << token[i] << endl;
cout << endl;
outfile<< "Output tokens" <<token;
infile.close();
outfile.close();
}
system("pause");
return 0;
}
Since you have tagged your question as C++, I recommend using the C++ language features as they are safer (less defects injected) than C.
For example, replace char * with std::string. The std::string has more features for lexing or searching than the C-Style string functions (str*()).
For your projects, I don't recommend using regular expressions. Getting them to work correctly may take you longer than implement a simple lexer.
Edit 1
For more specific help, please edit your question with the syntax rules of the language you are parsing.
One simple technique is to isolate "words" or identifiers from symbols.
Also read up on Backus-Naur notation
Your issue is too complicated (in the big picture) to be answered in StackOverflow.
Edit 2 - Example
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
int main(void)
{
std::ifstream input("input.txt");
if (!input)
{
std::cerr << "Error opening \"input.txt\".\r\n";
return 1;
}
// Read the file.
std::string input_text;
while (std::getline(input, input_text))
{
static const char white_space[] = " \t";
static const char identifier_letters[] = "abcdefghijklmnopqrstuvwxyz";
std::string::size_type position = 0;
if (input_text.length() == 0)
{
continue; // Empty line
}
// Skip white space.
position = input_text.find_first_not_of(white_space, 0);
if ((position == std::string::npos)
{
continue; // Blank line.
}
// Check if the first (non-whitespace character) is a
// valid identifier letter
if (std::isalpha(input_text[position]))
{
// First character is a letter.
// Find the end of the identifier.
std::string::size_type identifier_end_posn = 0;
identifier_end_posn = input_text.find_first_not_of(identifier_letters, position);
if (identifier_end_posn != std::string::npos)
{
const int identifier_length = identifier_end_posn - position + 1;
std::string identifier = input_text.substr(position, identifier_length);
cout << identifier << "\n";
continue;
}
}
}
return 0;
}
You will need to augment the above code to look for symbols and numbers.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I will first off say that yes, this is a homework assignment, but my teacher is really not too clear on how to do things.
I'm asked to, in c++, Write a function that will pass words from a file one at a time. The function will calculate the word length and then print out TO SCREEN the word and its length on its own line.
The main will open your input file, read it word by word in a loop and then pass the word into your function for it to be printed.
I know how to open a file using fstream and all that, read it word by word, but not in a loop or a function by the void readfile () one. My problem here is putting everything together.
This is my program to open a file, get the length and display it in a parallel array
//declare parallel arrays
string words [MAXSIZE];
//open files
outputFile.open("output.txt");
inputFile.open ("/Users/cathiedeane/Documents/CIS 22A/Lab 4/Lab 4 Part 2/lab4.txt");
//inputvalidation
while (!inputFile.eof())
{
for(int i = 0; i < MAXSIZE; ++i)
{
outputFile << words[i] << " " << endl;
inputFile >> words[i];
}
inputFile.close();
}
for (int i= 0; i <= MAXSIZE; i++)
{ cout << words[i] << ":" << words[i].size()<< endl;
outputFile << endl;
}
//close outputfile
outputFile.close();
return 0;
}
So basically your assignment is :
function read_word
/* what you have to work on */
end
function read_file_word_by_word
open file
while not end_of_file
word = read_word
print word, word_length
end
close file
end
To read a word, you need to define what it is. Usually it's a bunch of letters, delimited by other characters that are not letters (whitespace, commas, etc.).
You could read the file character by character and store them when they are letters until you encounter some other kind of character. What you have stored is a word, and you can get its length quite easily.
Tip: http://www.cplusplus.com/reference/istream/istream/get/ allows you to read a single character from a file.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
void func(const string& word)
{
//set field width
cout.width(30);
cout << left << word << " " << word.size() << endl;
}
int main(int argc, char* argv[])
{
ifstream ifs("F:\\tmp\\test.txt");
if(ifs.fail())
{
cout << "fail to open file" << endl;
return -1;
}
_Ctypevec ct = _Getctype();
for(char ch = 0; ch < SCHAR_MAX; ch++)
{
//set all punctuations as field separator of extraction
if(ispunct(ch))
{
(const_cast<short*>(ct._Table))[ch] = ctype<char>::space;
}
}
//change the default locale object of ifstream
ifs.imbue(locale(ifs.getloc(), new ctype<char>(ct._Table)));
string word;
while(ifs >> word)
{
func(word);
}
ifs.close();
}
You'll obviously want to separate each word in to its own string index to store them in your array. To separate each word, establish a break point like char break = ' '; Then, while your IOStream is reading the file, just add the words to the index using an iterator (i++)
Now that some time has passed since you asked the question, I would like to add that this could be answered in a quite small amount of code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void printString( const string & str ) { // ignore the & for now, you'll get to it later.
cout << str << " : " << str.size() << endl;
}
int main() {
ifstream fin("your-file-name.txt");
if (!fin) {
cout << "Could not open file" << endl;
return 1;
}
string word; // You only need one word at a time.
while( fin >> word ) {
printString(word);
}
fin.close();
}
A small note on fin >> word, this expression returns true for as long as there was a word read into the string. It will also skip any whitespace (tab, space and newline) by default.