I have been struggling with comparing two strings which I read from files, "one" & "two" both have the same words (e.g. salt) but it doesn't return "Equal". I have also used == but it made no difference.
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
int main (){
string en[100];
string line;
int i=0;
ifstream fileEn ("hey.txt");
if (fileEn.is_open()){
while (!fileEn.eof()){
getline(fileEn,line);
en[i]=line;
i++;
}
}
fileEn.close();
string fa[100];
string line1;
i=0;
ifstream fileFa ("hey1.txt");
if (fileFa.is_open()){
while (!fileFa.eof()){
getline(fileFa,line1);
fa[i]=line1;
i++;
}
}
fileFa.close();
ifstream Matn("matn.txt");
string matn[100];
if(Matn.is_open()){
for(int i = 0; i < 100; ++i){
Matn >> matn[i];
}
}
Matn.close();
string one = en[0];
string two = matn[0];
cout << one << " " << two;
if(one.compare(two) == 0){
cout << "Equal";
}
}
I suggest adding some debugging output to your program:
while (!fileEn.eof()){
getline(fileEn,line);
// Debugging output
std::cout << "en[" << i << "] = '" << line << "'" << std::endl;
en[i]=line;
i++;
}
and
for(int i = 0; i < 100; ++i){
Matn >> matn[i];
// Debugging output
std::cout << "matn[" << i << "] = '" << matn[i] << "'" << std::endl;
}
Hopefully you can see what the problem is by looking at the output.
In addition, please note that use of while (!fileEn.eof()){ ... } is not correct. See Why is iostream::eof inside a loop condition considered wrong?.
I suggest changing that loop to:
while (getline(fileEn,line)) {
// Debugging output
std::cout << "en[" << i << "] = '" << line << "'" << std::endl;
en[i]=line;
i++;
}
Similarly, don't assume that Matn >> matn[i] is successful. I suggest changing that loop to:
for(int i = 0; i < 100; ++i) {
std::string s;
if ( !(Matn >> s) )
{
// Read was not successful. Stop the loop.
break;
}
matn[i] = s;
// Debugging output
std::cout << "matn[" << i << "] = '" << matn[i] << "'" << std::endl;
}
Related
i am storing some data in the file but after
if (titlemap.count(words[i]) == 1)
is reached i reopened the file and reading all data in a vector and then storing updated data but
But actually the program is not going into the below loop.
for (int j = 0; j < vec.size(); j++)
Can anyone suggest why is it so? I am very confused and frustrated
// Cmarkup1.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include"Markup.h"
#include <msxml.h>
#include <ctime>
#include <unordered_map>
#include <cctype>
#include <string>
#include <functional>
#include <algorithm>
#include "functions.h"
#include <map>
#include <fileapi.h>
using namespace std;
int main()
{
// Open the file for parsing.
ofstream wfile("title.txt");
bool check = false;
string delimiter = " ,:,";
int results = 0, pages = 1;
time_t timer;
timer = clock();
CMarkup xmlfile;
unordered_map<string, string> titlemap;
unordered_map<string, string> textmap;
vector <string> words;
xmlfile.Load(MCD_T("simplewiki-latest-pages-articles.xml"));
xmlfile.FindElem();
xmlfile.IntoElem();
int line=0;
while (xmlfile.FindElem(MCD_T("page"))) {
xmlfile.IntoElem();
xmlfile.FindElem(MCD_T("title"));
MCD_STR(title);
title = xmlfile.GetData();
string str(title.begin(), title.end());
transform(str.begin(), str.end(), str.begin(), ::tolower);
split(words, str, is_any_of(delimiter));
for (int i = 0; i < words.size(); i++) {
if (titlemap.count(words[i]) == 1) {
ifstream rfile;
rfile.open("title.txt");
vector<string> vec;
string line;
while (getline(rfile, line)) {
vec.push_back(line);
}
for (int j = 0; j < vec.size(); j++) {
if (words[i] == vec[j]) {
cout << vec[j] <<"Checking"<< endl;
wfile << vec[j] << ",page" << pages << endl;
}
else
wfile << vec[j] << endl;
//wfile.close();
}
}
else {
//wfile.open("title.txt");
keeponlyalphabets(words[i]);
titlemap.insert(make_pair(words[i], words[i]));
wfile << words[i] <<"-page"<<pages<< endl;
++line;
}
}
words.clear();
//cout << str << endl;
//xmlfile.FindElem(MCD_T("text"));
//MCD_STR(text);
//text = xmlfile.GetData();
//string str1(text.begin(), text.end());
//transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
//str1 = keeponlyalphabets(str1);
//removestopwords(str1);
//textmap.insert(make_pair(str1, str1));
//cout << str1 << endl;
if (pages > 100)
break;
pages++;
xmlfile.OutOfElem();
}
wfile.close();
// for (auto it : titlemap)
// cout << it.first << endl;
cout << "Total lines are as: "<<line << endl;
/*string input;
cout << "press s to seach the data" << endl;
getline(cin, input);
if (input == "s") {
string key;
cout << "Enter Key" << endl;
cin >> key;
transform(key.begin(), key.end(), key.begin(), ::tolower);
size_t temp;
cout << endl;
for (auto it = data.begin(); it != data.end(); it++) {
//temp = it->first.find(key);
//cout << temp;
if (it->first.find(key) != std::string::npos) {
cout << it->second << endl;
results++;
}
}
}
else
cout << "Invalid Character Exiting....." << endl;
timer = clock() - timer;
cout << "Total time taken by the process is: " << (float)timer / CLOCKS_PER_SEC << endl;
cout << " Total Results : " << results << endl;
*/
return 0;
}
You have separate streams opened against the file, with separate buffers on each. writeing to a file only actually writes to disk infrequently (typically when a buffer fills, which may take a while for small writes, and always just before the file is closed). So when you re-open the file for read, it won't see anything still stuck in user-space buffers.
Just add:
wfile.flush()
prior to opening for read, to ensure the buffers are flushed to disk and available to the alternate handle.
So in this program I'm trying to go through word by word and make it only lowercase letters, no whitespace or anything else. However, my string "temp" isn't holding anything in it. Is it because of the way I'm trying to modify it? Maybe I should try using a char * instead? Sorry if this is a stupid question, I'm brand new to c++, but I've been trying to debug it for hours and can't find much searching for this.
#include <string>
#include <iostream>
#include <fstream>
#include <ctype.h>
using namespace std;
int main(int argc, char* argv[]) {
/*if (argc != 3) {
cout << "Error: wrong number of arguments." << endl;
}*/
ifstream infile(argv[1]);
//infile.open(argv[1]);
string content((std::istreambuf_iterator<char>(infile)),
(std::istreambuf_iterator<char>()));
string final;
string temp;
string distinct[5000];
int distinctnum[5000] = { 0 };
int numdist = 0;
int wordcount = 0;
int i = 0;
int j = 0;
int k = 0;
int isdistinct = 0;
int len = content.length();
//cout << "test 1" << endl;
cout << "length of string: " << len << endl;
cout << "content entered: " << content << endl;
while (i < len) {
temp.clear();
//cout << "test 2" << endl;
if (isalpha(content[i])) {
//cout << "test 3" << endl;
if (isupper(content[i])) {
//cout << "test 4" << endl;
temp[j] = tolower(content[i]);
++j;
}
else {
//cout << "test 5" << endl;
temp[j] = content[i];
++j;
}
}
else {
cout << temp << endl;
//cout << "test 6" << endl;
++wordcount;
final = final + temp;
j = 0;
for (k = 0;k < numdist;k++) {
//cout << "test 7" << endl;
if (distinct[k] == temp) {
++distinctnum[k];
isdistinct = 1;
break;
}
}
if (isdistinct == 0) {
//cout << "test 8" << endl;
distinct[numdist] = temp;
++numdist;
}
}
//cout << temp << endl;
++i;
}
cout << wordcount+1 << " words total." << endl << numdist << " distinct words." << endl;
cout << "New output: " << final << endl;
return 0;
}
You can't add to a string with operator[]. You can only modify what's already there. Since temp is created empty and routinely cleared, using [] is undefined. The string length is zero, so any indexing is out of bounds. There may be nothing there at all. Even if the program manages to survive this abuse, the string length is likely to still be zero, and operations on the string will result in nothing happening.
In keeping with what OP currently has, I see two easy options:
Treat the string the same way you would a std::vector and push_back
temp.push_back(tolower(content[i]));
or
Build up a std::stringstream
stream << tolower(content[i])
and convert the result into a string when finished
string temp = stream.str();
Either approach eliminates the need for a j counter as strings know how long they are.
However, OP can pull and endrun around this whole problem and use std::transform
std::transform(content.begin(), content.end(), content.begin(), ::tolower);
to convert the whole string in one shot and then concentrate on splitting the lower case string with substring. The colons in front of ::tolower are there to prevent confusion with other tolowers since proper namespacing of the standard library has been switched off with using namespace std;
Off topic, it looks like OP is performing a frequency count on words. Look into std::map<string, int> distinct;. You can reduce the gathering and comparison testing to
distinct[temp]++;
I have the next function and i want to print some parameters separated by a comma, my problem is that the console didn't show anything when "parametro[i] = linea[i]" in the FOR iteration.
Example:
Parametro 1: []
void funcionSeparadora (string linea){
int numParametros = 1;
string parametro;
for (int unsigned i=0;i<linea.length();i++){
if (linea[i] == ','){
cout <<"Parámetro "<<numParametros<<": "<<"["<< parametro <<"]"<< '\n';
numParametros++;
}
else (parametro[i] = linea[i]);
}
}
Mostly the way you handle the filling of parametro was wrong. Fixed version:
void funcionSeparadora(string linea) {
int numParametros = 1;
string parametro;
for (int unsigned i = 0; i<linea.length(); i++) {
if (linea[i] == ',') {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << '\n';
numParametros++;
parametro.clear();
}
else {
parametro += linea[i];
}
}
if (!parametro.empty()) {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << '\n';
}
}
Points you missed
Use curly brackets in else condition
Use size_t instead of unsigned in in for loop
initialize the parametro variable with necessary length
Try this
#include <iostream>
#include <string>
using namespace std;
void funcionSeparadora(string linea) {
int numParametros = 1;
string parametro(linea.length(),' ');
for (size_t i = 0; i < linea.length(); i++) {
if (linea[i] == ',') {
cout << "Parámetro " << numParametros << ": " << "[" << parametro << "]" << endl;
numParametros++;
}
else {
parametro[i] = linea[i];
}
}
}
int main()
{
funcionSeparadora("what is this,");
system("pause");
return 0;
}
Firstly here is my code I have so far:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int arraysize = 35;
int i = 0;
string line;
string searchTerm;
int main()
{
string words[arraysize];
ifstream wordFile;
wordFile.open ("wordFile.txt");
if (wordFile.is_open())
{
while (! wordFile.eof())
{
getline (wordFile, line);
words[i] = line;
i++;
}
wordFile.close();
}
else
{
cout << "Unable to open file" << endl;
}
for (int x = 0; x < arraysize; x++)
{
cout << words[x] << " ";
}
cout << "\n\nEnter in a word you would like to search in the story above:" << endl;
cin >> searchTerm;
for (int y = 0; y < arraysize; y++)
{
if (words[y].compare(searchTerm) !=0)
{
cout << "No match found" << endl;
}
}
}
What I have so far is the program reading from a textfile and then printing those words. What I wanna do next is let the user enter in a word that they would like to search in the textfile, if there is a word like the one they entered print that word if there isn't print out "There isn't a word like that in the textfile"
I just cant get the searching figured out, any suggestions on how to do this?
Here is an example of how you would search for strings within strings
// string::find
#include <iostream> // std::cout
#include <string> // std::string
int main ()
{
std::string str ("There are two needles in this haystack with needles.");
std::string str2 ("needle");
// different member versions of find in the same order as above:
std::size_t found = str.find(str2);
if (found!=std::string::npos)
std::cout << "first 'needle' found at: " << found << '\n';
found=str.find("needles are small",found+1,6);
if (found!=std::string::npos)
std::cout << "second 'needle' found at: " << found << '\n';
found=str.find("haystack");
if (found!=std::string::npos)
std::cout << "'haystack' also found at: " << found << '\n';
found=str.find('.');
if (found!=std::string::npos)
std::cout << "Period found at: " << found << '\n';
// let's replace the first needle:
str.replace(str.find(str2),str2.length(),"preposition");
std::cout << str << '\n';
return 0;
}
This should help you figure out exactly what you need to do
Notice how parameter pos is used to search for a second instance of the same search string. Output:
first 'needle' found at: 14
second 'needle' found at: 44
'haystack' also found at: 30
Period found at: 51
There are two prepositions in this haystack with needles.
How about:
int found = -1;
for (int y = 0; y < arraysize; y++)
{
if (words[y].compare(searchTerm) ==0)
{
found = y;
break;
}
}
if ( found != -1 )
cout << "found!" << endl;
else
cout << "No match found" << endl;
or shorter:
if ( std::find(std::begin(words), std::end(words), searchTerm) == std::end(words) )
cout << "not found";
else
cout << "found";
I want to convert an int to a string so can cout it. This code is not working as expected:
for (int i = 1; i<1000000, i++;)
{
cout << "testing: " + i;
}
You should do this in the following way -
for (int i = 1; i<1000000, i++;)
{
cout << "testing: "<<i<<endl;
}
The << operator will take care of printing the values appropriately.
If you still want to know how to convert an integer to string, then the following is the way to do it using the stringstream -
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
int number = 123;
stringstream ss;
ss << number;
cout << ss.str() << endl;
return 0;
}
Use std::stringstream as:
for (int i = 1; i<1000000, i++;)
{
std::stringstream ss("testing: ");
ss << i;
std::string s = ss.str();
//do whatever you want to do with s
std::cout << s << std::endl; //prints it to output stream
}
But if you just want to print it to output stream, then you don't even need that. You can simply do this:
for (int i = 1; i<1000000, i++;)
{
std::cout << "testing : " << i;
}
Do this instead:
for (int i = 1; i<1000000, i++;)
{
std::cout << "testing: " << i << std::endl;
}
The implementation of << operator will do the necessary conversion before printing it out. Use "endl", so each statement will print a separate line.