Reading in input to construct an object - c++

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.

Related

Ifstream not retrieving data using array in C++

I've been trying to read data from employee-info.txt using ifstream and storing it in an array, but it did not read anything.
The main goal of my code is, every time that it was able to read a value in employee-info.txt, It will loop and the integer variable valueChecker will increment by one. After the loop is done, the value of valueChecker will be returned in order to determine how many strings are retrieved from employee-info.txt. Based on the contents of employee-info.txt, it should return an int of 8, but it is only returning an int of 0, which is the initialized value.
I also checked through debugger and the record array did not read anything from the file. I already checked the address of the file and it is correct.
Here is the code in Employee.h:
#pragma once
#include<string>
#include<iostream>
class Employee
{
public:
struct EmployeeRecord {
static const int recordSize = 100;
static const int fieldSize = 4;
std::string record[recordSize][fieldSize];
};
public:
Employee();
~Employee();
int employeeDataChecker();
void employeeWriteData();
void employeeDisplayData();
EmployeeRecord& employeeReturnRecordArray();
private:
EmployeeRecord emp_record;
};
Employee.cpp:
#include "Employee.h"
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
int Employee::employeeDataChecker()
{
//Check if there are data in the employee-info.txt
EmployeeRecord emp;
int valueChecker = 0;
std::ifstream inFile;
inFile.open("C:\\Users\\RJ\\Desktop\\employee-info.txt");
for (int index = 0; index < emp.recordSize; index++) {
for (int index2 = 0; index2 < emp.fieldSize; index2++) {
while (inFile >> emp.record[index][index2]) {
valueChecker++;
}
}
}
inFile.close();
return valueChecker;
}
employee-info.txt:
ID Firstname Lastname Sales
1 Joe Satriani 500000.00
Yes, first, you have to check if file is correctly opened (i.e. inFile.is_open()).
Then, forget iteration on fields and try to do something like this:
int id;
char firstname[64] = { 0 };
char lastname[64] = { 0 };
float sales;
inFile >> id;
inFile.get(firstname, 64, ' ');
inFile.get(lastname, 64, ' ');
inFile >> sales;
On failure, [inFile >>] operator could return false and then it wont increment valueChecker.

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;
}

Searching for an int inside a file

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?

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;
}