Searching for an int inside a file - c++

So I am supposed to take all ints in source3.txt and check which of them occur in source.txt. If any of them don't occur, I'm supposed to print a corresponding line from source2.txt to output.txt (source2.txt contains descriptions of the numbers in source 3, in the same order, each description is 1 line). I wrote this code, but it only prints the last line from source2.txt, furthermore it is a wrong line.
I have no idea what might be wrong. Can you help me?
#include <bits/stdc++.h>
using namespace std;
int main()
{
ifstream source ("source.txt");
ifstream source2 ("source2.txt");
ifstream source3 ("source3.txt");
vector<int> tab(1051,0);
vector<string> tab2(857,*new string);
vector<int> tab3(857,0);
ofstream output("output.txt");
for(int i=0;i<1050;++i)
{
source>>tab[i];
}
for(int i=0;i<856;++i)
{
string a;
getline(source2,a);
tab2[i]=a;
source3>>tab3[i];
}
for(int i=0;i<856;++i)
{
if(std::find(tab.begin(), tab.end(), tab3[i]) != tab.end())
{
continue;
}
else
{
output<<tab2[i]<<endl;
}
}
}

I think below modifications to code should work for you . Replace value of SOURCE_COUNT with 1051 and SOURCE2_COUNT with 857
#include <iostream>
#include <fstream>
#include <vector>
#include <vector>
const int SOURCE_COUNT = 4;
const int SOURCE2_COUNT = 3;
//const int SOURCE2_COUNT = 3;
using namespace std;
int main()
{
ifstream source ("source.txt");
ifstream source2 ("source2.txt");
ifstream source3 ("source3.txt");
vector<int> tab(SOURCE_COUNT,0);
vector<string> tab2(SOURCE2_COUNT,"");
vector<int> tab3(SOURCE2_COUNT,0);
ofstream output("output.txt");
for(int i=0;i<SOURCE_COUNT;++i)
{
source>>tab[i];
}
for(int i=0;i<SOURCE2_COUNT;++i)
{
string a;
getline(source2,a);
tab2[i]=a;
source3>>tab3[i];
}
for(int i=0;i<SOURCE2_COUNT;++i)
{
if(std::find(tab.begin(), tab.end(), tab3[i]) != tab.end())
{
continue;
}
else
{
output<<tab2[i]<<endl;
}
}
}

It looks to me like you are printing only in those cases where you have not found the number. In other words, the cases in your if-statement are reversed. It should read:
if(std::find(tab.begin(), tab.end(), tab3[i]) != tab.end())
output<<tab2[i]<<endl;
[EDIT] Oops, I read the question not carefully enough. It should print the line, if the number is NOT contained in source3. So the loop should read:
if(std::find(tab.begin(), tab.end(), tab3[i]) == tab.end())
output<<tab2[i]<<endl;
Also: I would strongly suggest to do away with all those constants like 856 and 1050. Why don't you simply read the file until you reach the end?

Related

C++ Array pointer-to-object error

I am having what seems to be a common issue however reading through the replies to the similar questions I can't find the solution to my issue at all as I have already done what they are suggesting such as making the variable an array. I have the following code:
#include "stdafx.h"
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <future>
using namespace std;
string eng2Str[4] = { "money", "politics", "RT", "#"};
int resArr[4];
int main()
{
engine2(eng2Str[4], resArr[4]);
system("Pause");
system("cls");
return 0;
}
void engine2(string &eng2Str, int &resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++) {
while (getline(fin, line)) {
if (line.find(eng2Str[i]) != string::npos) {
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
Before you mark as duplicate I have made sure of the following:
The array and variable I am trying to assign are both int
Its an array
The error is:
expression must have pointer-to-object type
The error is occurring at the "resArr[i] = fcount;" line and am not sure why as resArr is an int array and I am trying to assign it a value from another int variable. I am quite new to C++ so any help would be great as I am really stuck!
Thanks!
The problem is that you've declared your function to take a reference to a single string and int, not arrays. It should be:
void engine2(string *eng2Str, int *resArr)
or:
void engine2(string eng2Str[], int resArr[])
Then when you call it, you can give the array names as arguments:
engine2(eng2Str, resArr);
Another problem is the while loop in the function. This will read the entire file during the first iteration of the for() loop. Other iterations will not have anything to read, since it will be at the end of the file already. You could seek back to the beginning of the file, but a better way would be to rearrange the two loops so you just need to read the file once.
while (getline(fin, line)) {
for (int i = 0; i < 4; i++) {
if (line.find(eng2Str[i]) != string::npos) {
resArr[i]++;
}
}
}
I would suggest to use std::vector instead of pure C array.
In your code, there are more issues.
You are passing the fourth element of both arrays to the engine2 function.
From your definition of void engine2(string &eng2Str, int &resArr) you expect reference to a string (not array / vector) and an address / reference of int - you need to pass an pointer to the first element of resArr.
#include <cstring>
#include <fstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <future>
using namespace std;
vector<string> eng2Str = { "money", "politics", "RT", "#" };
int resArr[4] = {};
void engine2(const vector<string>& eng2Str, int* resArr)
{
ifstream fin;
fin.open("sampleTweets.csv");
int fcount = 0;
string line;
for (int i = 0; i < 4; i++)
{
while (getline(fin, line))
{
if (line.find(eng2Str[i]) != string::npos)
{
++fcount;
}
}
resArr[i] = fcount;
}
fin.close();
return;
}
int main()
{
engine2(eng2Str, resArr);
system("Pause");
system("cls");
return 0;
}

Reading in input to construct an object

I am trying to read a string line for line down a .txt file in order to initiate an array of objects using a constructor that takes a string.
The text file is written like
TransAm
Mustang
Corvette
I feel like my loop is not iterating the information I want to be set correctly. Is there an easy way of accomplishing this?
main.cc
#include <string>
#include <iostream>
#include "Car.cc"
#include <fstream>
using namespace std;
int main()
{
Car cars[3];
string STRING;
ifstream infile;
infile.open("cars.txt");
// THIS IS HOW IT'S ACHIEVED USING FOR-LOOP - Sam
for(int i = 0; i<3 && infile;++i){
getline(infile,STRING);
cars[i].setName(STRING);
}
/* THIS IS WHAT I HAD
while(!infile)
{
getline(infile,STRING);
for(int i = 0; i<sizeof(cars);i++){
cars[i].setName(STRING);
}
}
*/
infile.close();
for(int j = 0;j<sizeof(cars);j++){
cars[j].print();
}
}
Car.h
#include <string>
using namespace std;
class Car{
public:
Car();
Car(string);
string getName();
void setName(string);
void print();
private:
string name;
};
Car.cc
#include <string>
#include "Car.h"
using namespace std;
Car::Car()
{
}
Car::Car(string s)
{
setName(s);
}
void Car::setName(string s)
{
name = s;
}
string Car::getName()
{
return name;
}
void Car::print()
{
cout << name;
}
These points need to be corrected:
while (!infile) prevents you from entering the loop.
You don't need two loops.
You can modify your loop like this:
for (int i = 0; i < sizeof(cars) && getline(infile, STRING); ++i)
cars[i].setName(STRING);
Or like this:
for (int i = 0; i < sizeof(cars) && infile; ++i) {
getline(infile, STRING);
cars[i].setName(STRING);
}
Your loop does at the moment nothing if the file is correctly opened. It will only enter if the call to open was unsuccessful.
Change your loop to either
while (getline(infile,STRING))
{
//...
}
or
while (infile)
{
//...
}
As it's been said, "Change while(!infile) to while(getline(infile,STRING))" but do not forget to remove the getline(infile,STRING); afterwards.

Reading data into a struct array from a file

I have an input file that looks like this
1 0 3
2 11 5
3 15 1
4 16 11
and a structure that looks like this
struct numb {
int numb1;
int numb2;
int numb3;
}
and I need to create an array of the struct so that each element of the array holds all three numbers. So
numbArray[0].numb1 == 1
numbArray[0].numb2 == 0
numbArray[0].numb3 == 3
numbArray[1].numb1 == 2
numbArray[1].numb2 == 11
and so on. I've gotten the hang of opening and closing files, finding how many lines there are in a file, and reading a single line from a file, but I do not know how to store individual elements from a line.
My program looks like this so far:
#include <iostream>
#include <fstream>
#include <string>
int main(int argc, char* argv[])
{
ifstream inFile(argv[1]);
int fileLength = 0;
std::string line;
while(std::getline(inFile, line))
{
++fileLength;
}
struct numb {
int numb1;
int numb2;
int numb3;
}
if(inFile.is_open())
{
for(unsigned i = 0; i <= fileLength; i++)
{
//What to do here?
}
}
}
Use getline when you don't have regular structure to the input and need to handle variation between lines. When your input file has regular structure (in this case, there are always three values per line), then simply use the stream extraction operators directly:
#include <iostream>
#include <vector>
struct group
{
int n1;
int n2;
int n3;
};
int main()
{
std::vector<group> groups;
while (std::cin)
{
group line;
line.n1 << std::cin;
line.n2 << std::cin;
line.n3 << std::cin;
groups.push_back(group);
}
}
Express your ideas directly in code as much as possible.
Note I've written the code assuming that the file is in the proper form. If there are too many or too few values per line, then the above code will be confused. However, it is best to code the simplest thing that could possibly work and worry about complexity when you need it. In your example you stated that the input file was well-formed, so there's no need to overcomplicate things.
I recommend using a std::stringstream for this:
#include <iostream>
#include <sstream>
#include <string>
#include <stdio.h>
#include <vector>
struct numb {
int numb1;
int numb2;
int numb3;
};
void populate(std::vector<numb>& my_numbs, std::string line) {
std::stringstream ss(line);
numb my_numb;
ss >> my_numb.numb1 >> my_numb.numb2 >> my_numb.numb3;
my_numbs.push_back(my_numb);
}
void output(const numb my_numbs) {
printf("%d %d %d\n", my_numbs.numb1, my_numbs.numb2, my_numbs.numb3);
}
int main(int argc, char* argv[]) {
ifstream inFile(argv[1]);
std::string line;
std::vector<numb> my_vect;
while(std::getline(inFile, line)) {
populate(my_vect, line);
}
for(size_t i = 0; i < my_vect.size(); ++i) {
std::cout << "my_vect[" << i << "]:";
output(my_vect[i]);
}
return 0;
}
std::stringstreams allow you to parse out data types from std::strings, you you just need to parse out 3 ints, which you can use with your struct. You then push the struct into your vector.
Here's the working ideone taking input from stdin.
You should probably be able to do something like this:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main(int argc, char* argv[])
{
ifstream inFile(argv[1]);
int fileLength = 0;
std::string line;
struct numb {
int numb1;
int numb2;
int numb3;
};
vector<vector<int>> sets;
int n1, n2, n3;
while (std::cin >> n1)
{
cin >> n2;
cin >> n3;
vector<int> vec;
vec.push_back(n1);
vec.push_back(n2);
vec.push_back(n3);
sets.push_back(vec);
}
numb * numbSet = new numb[sets.size()];
//Since the vectors data is continuous in memory just as the array of structs are
//you can just copy the data directly
for (int i = 0; i < sets.size(); i++)
{
std::memcpy(&numbSet[i], &sets[i][0], sizeof(numb));
}
}

Loop won't stop at end of file

I'm working on file io, and i've managed to get the data from the file into the vector i made, but when i print the values, i get garbage numbers after the last part of the data. So i'm guessing its pushing values that don't exist into the vector, or its trying to print parts of the vector that don't exist. Any help would be great.
main.cpp
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>
#include "store.h"
using namespace std;
int main ()
{
store data;
ifstream inFile ("C:/Users/Owner/Desktop/Albums.csv");
string line;
string item;
int num;
int itemnum;
int linenum = 1;
ostringstream convert;
string temp;
while (!inFile.eof())
{
while (getline (inFile, line) )
{
istringstream linestream(line);
itemnum = 0;
num = 0;
convert << linenum;
temp = convert.str();
data.addtovectv(temp);
while (getline (linestream, item, ',') )
{
if (itemnum == 1 || itemnum == 2 || itemnum == 3 || itemnum == 5)
{
num++;
data.addtovectfullline(0, item);
}
itemnum++;
}
linenum++;
}
}
data.print();
inFile.close();
return 0;
}
store.h
#ifndef STORE_H
#define STORE_H
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
class store
{
public:
store();
void addtovectv(string);
void addtovectfullline(int, string);
void print();
private:
vector<string> v;
vector< vector<string> > fullline;
};
#endif
store.cpp
#include "store.h"
store::store()
{
}
void store::addtovectv(string a)
{
v.push_back(a);
fullline.push_back(v);
}
void store::addtovectfullline(int a, string c)
{
fullline[a].push_back(c);
}
void store::print()
{
for(unsigned int i=0; i<fullline.size(); i++)
{
for(unsigned int j=0; j<fullline[i].size(); j++)
{
cout << fullline[i][j] << endl;
}
cout << endl;
}
}
edit: some sample data
RS 500 compilations, Various Artists, The Sun Records Collection, 308
Both lists, A Tribe Called Quest, The Low End Theory, 1991, 154, Jive, Skeff Anselm, Zombart JK, USA, 48:08:52
Both lists, AC/DC, Back in Black, 1980, 73, ATCO, Robert John Lange, Bob Defrin, Australia / UK, 41:36:52
Both lists, AC/DC, Highway to Hell, 1979, 199, Albert Productions, Robert John Lange, Bob Defrin Australia / UK, 41:53:52
i need to read the lines, but only put the second, third, fourth, and sixth piece of info into the vectors, which is what it should end up printing, with each individual piece on a new line. All the data is stored in a .csv file
with this sample data, my output is this screenshot: http://puu.sh/bHtHM.png
however, none of those numbers at the bottom should be there, and there is a weird space after the first set of data
edit2: realized that odd space was an absence of the data i asked for, so its fine
In.good() is not the appropriate way to tell if the file is done.
(From http://www.cplusplus.com/reference/ios/ios/good/)
Ios::eof() checks for end of file.
Ios::Good() checks for no errors in opening. It probably exits the loop when an error occurs from reading past EOF.

remove stopwords then apply case folding ( how to combine two codes)

I have a txt file called aisha includes this
This is a new file I did it for mediu.
Its about Removing stopwords fRom the file
and apply casefolding to it
I Tried doing that many Times
and finally now I could do
and I wrote two codes one is to remove some stop words from it
#include <iostream>
#include <string>
#include <fstream>
int main()
{
using namespace std;
ifstream file("aisha.txt");
if(file.is_open())
{
string myArray[200];
for(int i = 0; i < 200; ++i)
{
file >> myArray[i];
if (myArray[i] !="is" && myArray[i]!="the" && myArray[i]!="that"&& myArray[i]!="it"&& myArray[i]!="to"){
cout<< myArray[i]<<" ";
}
}
}
system("PAUSE");
return 0;
}
and the other is for apply casefolding for four ketters
#include <iostream>
#include <string>
#include <fstream>
int main()
{
using namespace std;
ifstream file("aisha.txt");
if(file.is_open())
{
file >> std::noskipws;
char myArray[200];
for(int i = 0; i < 200; ++i)
{
file >> myArray[i];
if (myArray[i]=='I')
cout<<"i";
if (myArray[i]=='A')
cout<<"a";
if (myArray[i]=='T')
cout<<"t";
if (myArray[i]=='R')
cout<<"r";
else
if (myArray[i]!='I' && myArray[i]!='T' && myArray[i]!='R')
cout<<myArray[i];
}
file.close();
}
system("PAUSE");
return 0;
}
now that I need to combine these two codes into one code that remove stopwords and then apply case folding
the problem that I used string myArray[200]; for the stopwords codeand char myArray[200]; for the case folding code
and I cant use only string or only char
what can I do ?
Put the text processors in separate functions and call them one by one in main. There will be no names and types collisions.
Here is rough example
void removeStopWords(ifstream file) {
// put your code here for removing the stopwords
}
void applyCaseFolding(ifstream file) {
// put your code here for applying case folding
}
int main() {
ifstream file("aisha.txt");
if(file.is_open()) {
removeStopWords(file);
applyCaseFolding(file);
}
return 0;
}