Reading arrays from binary file C++ - c++

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <fstream>
using namespace std;
int main()
{
srand(time(0));
const int array_size=10,n=10;
int i,j,k;
fstream io("io.dat", ios_base::binary);
float a[array_size];
for (i=0;i<n;i++) {
cout<<"Inputting "<<i+1<<" array:\n";
for (j=0;j<array_size;j++) {
a[j]=(float)rand()/(RAND_MAX+1)*200-100;
cout<<i+1<<"["<<j<<"]="<<a[j]<<endl;
}
io.write((char *)&a,sizeof(a));
}
io.close();
io.open("io.dat", ios_base::binary);
j=1;
while (!io.eof()) {
cout<<"Reading "<<j<<" array:"<<endl;
io.read((char *)&a,sizeof(a));
for (i=0,k=0;i<array_size;i++) {
cout<<j<<"["<<i<<"]="<<a[i]<<endl;
if (a[i]<0) k++;
}
cout<<"Number of negative elements in "<<j++<<" array="<<k<<endl;
}
return 0;
}
I am stuck in reading arrays from binary file. The problem is that condition of breaking reading cycle doesn't even works. Program reads the same array again and again.

This sort of a problem is caused because you are using !in.eof(). One of the easiest way to solve this is to read inside the while loop like in this code
io.open("io.dat", ios_base::binary);
j=1;
while ( io.read( (char *) &a, sizeof(a) ) ) // changed the !in.eof
{
cout<<"Reading "<<j<<" array:"<<endl;
// Removed the read form here
for (i=0,k=0;i<array_size;i++)
{
cout<<j<<"["<<i<<"]="<<a[i]<<endl;
if (a[i]<0) k++;
}
cout<<"Number of negative elements in "<<j++<<" array="<<k<<endl;
}
Well, that should solve the problem with your output.

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

rereading my file after extracting characters from it

I know this is a widely asked question and there are answers even on this website, unfortunately, none of the answers helped me with my problem which is the following: i open a file and loop over its characters to see how many rows i will need to initialize my dynamic array, then i have another loop to reread the file found out how many columns i have (i know this inst so efficient), then i will input these chars to my 2d dynamic array. We can see here i reread the file several times. I have tried commands like seekg(),rewind(), closing the file and re-opening it none have worked, here is my code : (we have been giving a hint that each row ends with value 0, that should not be counted.)Any help is much appreciated.
//------------- include section -------------
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <new>
#include <fstream>
#include <cstring>
#include <cctype>
//------------- using section -------------
using std::cin;
using std::cout;
using std::cerr;
using std::endl;
using std::ifstream;
using std::ofstream;
using std::setw;
//------------- const section -------------
const int END_OF_LINE=-1;
const int LEN=100;
//------------- prototypes section -------------
void open_files(ifstream& if1, ifstream& if2);
void convert_to_matrix (ifstream &inp,int*matrix[],int num_of_rows);
void add_2_matrixes (int*matrix[],int* matrix2[],int num_of_rows,int
num_of_rows2);
int get_length(ifstream & inp,int &length);
int get_rows(ifstream &inp, int &counter);
//------------- main -------------
int main(int argc, char *argv[])
{
ifstream inp;
ifstream inp2;
open_files(inp,inp2);
int num_of_rows=0,counter=0;
num_of_rows=get_rows(inp,counter);
int* matrix[num_of_rows];
//fill rows and cols dynamically
convert_to_matrix(inp,matrix,num_of_rows);
int num_of_rows2=0;
counter=0;
num_of_rows2=get_rows(inp2,counter);
//another matrix
int* matrix1[num_of_rows2];
//fill rows and cols dynamically
convert_to_matrix(inp2,matrix1,num_of_rows2);
add_2_matrixes(matrix,matrix1,num_of_rows,num_of_rows2);
return EXIT_SUCCESS;
}
//-----------------------------
void open_files(ifstream& inp, ifstream& inp2){
char* st_file;
char* nd_file;
st_file=new(std::nothrow) char [LEN];
nd_file=new(std::nothrow) char [LEN];
//gets the first file name
cin >> setw(LEN) >> st_file;
inp.open(st_file);
//gets the second file name
cin >> setw(LEN) >> nd_file;
inp2.open(nd_file);
// if the opening command failed
if ((!(inp.is_open())) || (!(inp2.is_open()))) {
exit(EXIT_FAILURE);
}
}
//------------------------------------------------
int get_rows(ifstream &inp, int &counter){
int columns=0;
while(!inp.eof())
{
counter++;
inp>>columns;
while (columns!=0)
{
inp>>columns;
}
}
//!!!! (problem)
inp.seekg(0,std::ios::beg);
return counter;
}
//---------------------------------------------
void convert_to_matrix (ifstream &inp,int* matrix[],int num_of_rows){
//numbers is how many cols
int length=0;
//value of each col
int number;
for (int row=0;row<num_of_rows;row++){
//open an array
get_length(inp,length);
matrix[row]=new(std::nothrow) int [length+1];
//if null we failed
if (matrix[row]==NULL)
{
cerr<<"Cannot allocate memory /n";
exit(EXIT_FAILURE);
}
//else start filling in values
for (number=0;matrix[row][number]!=0;number++)
{
inp>>matrix[row][number];
}
//at end of filling values last number is -1
//to help us know when to stop
matrix[row][number]=END_OF_LINE;
}
}
//------------------------------------------------------
int get_length(ifstream &inp,int &length){
int columns=0;
inp>>columns;
length++;
while(columns!=0)
{
inp>>columns;
length++;
}
//!!!!!(problem)
inp.seekg(0,std::ios::beg);
return length;
}

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?

wrong output in strings

My program calculates the length of each word before space and compares it with a fixed number.
The number is chosen from another string (pi).
I don't know why but my variable FLAG is always set to false so I always get the same output.
I don't know where the problem is. Please help out
#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <algorithm>
#include <iomanip>
using namespace std;
int main() {
int t=0,num;
int i,j,len,space;
bool FLAG;
string pi ="31415926535897932384626433833",song;
cin>>t;
while(t--){
len=0,space=0,i=0,j=0,num=0,FLAG=true;
cin.ignore();
getline(cin,song);
// problem from here
while(1) {
i=0,num=0,FLAG=true;
len=song.length();
space=song.find(' ');
if(space==-1){
if(len==pi[j]){
FLAG=true;
break;
}
else{
FLAG=false;
break;
}
}
else{
while(i<space){
num++;
i++;
}
if(num==pi[j]){
FLAG=true;
j++;
num=0;
i=0;
song.erase(0,space+1);
cout<<song<<endl;
}
else{
FLAG=false;
break;
}
}
}
// to here
if(FLAG==true){
cout<<"It's a pi song."<<"\n";
}
else{
cout<<"It's not a pi song."<<"\n";
}
}
return 0;
}
You are comparing an integer with a character value. i.e. you are comparing 3 with '3'. To get a number from a character digit, subtract '0'.
So you could write
if (len==(pi[j] - '0'))
Also, please learn to use a debugger, you can step through your code to find the line that doesn't work.

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