read a .dat file in c++ - c++

I am unable to read '.dat' file. I have tired all the possible ways and tired googling it but I could not find the solution. All it gives me is a null value for integer and a junk value for a string variable or char. This what I have written
ifstream file;
file.open("data1.dat"); // I have also tried this way too like file.open("data1.dat", ios::binary, ios::in);
int data=0;
file >> data;
cout << data << endl;
system("pause");
return 0;
I am using visual studio to compile this code. I am pretty sure that the pointer is entering into the data file but I don't know for what reason the data is not being read.
The .dat file consists of integer number per line ranging from 0, so I just need to read the file and get number from each line and should find the sum of all numbers in the file. The file contains number like
5,
468,
3200,
32, etc.,. Each number is in a new line. The file can contain any number of records. this how .dat file looks when opened using a notepad editor

Your code "works" on my system.
The following compiles (without "using namespace std;")
I changed the file name for my convenience.
I created the 't391.dat' file in the same working directory of the code, and put in 10 lines, with 1 value per line, 1..9,0.
#include <fstream>
#include <iostream>
int t391a(void)
{
std::ifstream file;
file.open("t391.dat");
int data=0;
file >> data;
std::cout << data << std::endl; // echo of input / proof it works
//system("pause");
file.close();
return 0;
}
This code outputs the first value (which is all it attempts to do), so it is working!
The echo of input is good idea.
As an experiment, I temporarily renamed the 't391.dat' file to something else. The code ran to completion and printed a single 0, which is not the first value in the file. Perhaps this suggests your file is not being found, I won't guess. To confirm, I restored the file, and the above 'works' again.
Missing items in your code:
error check - file.open()
a loop to read to end of file
error check - formatted extract (i.e. read from stream) of data item
file.close - possibly not needed
If you are still working this issue, I have a minimally extended version of your code that addresses these issues. Let me know.

class ValueGet {
public:
int data;
ValueGet() {
data = 0;
}
};
int main()
{
ValueGet vg;
ifstream file;
file.open("data1.dat", fstream::binary | fstream::out); // Opens a file in binary mode for input operations i.e., getting data from file.
if (!file)
cout << "File Not Found." << endl;
else {
file.seekg(0); // To make sure that the data is read from the starting position of the file.
while (file.read((char *)&vg, sizeof(vg))) // Iterates through the file till the pointer reads the last line of the file.
cout<<vg.data<<endl;
}
//system("pause");
return 0;
}
output of the data in the file

Here is one way which I just found
#include <bits/stdc++.h>
using namespace std;
int main(){
unsigned int a;
unsigned char c;
ifstream file;
file.open("ou.bin", ios::binary);
if(!file.is_open()){
cout<<"error";
return 0;
}
for(int i=0; i<8; i++){
file>>c;
a = c;
a = a<<8;
file>>c;
a = a+ c;
cout<<a<<endl;
}
file.close();
return 0;
}
This for storing two bytes in a number you can store as many bytes in a number or even one.
Hope this helps.

You will not be able to read .dat files and understand them in your context-- they are general formats used for storing data. Unless you know the contents of it or how they are specified, you will always get junk.

Related

why does removing blank space while writing into file fails reading files?

I'm learning C++, I find problems reading a file if I didn't add blank space while writing into it.
Plus, the file I wrote into doesn't contain blank space as intended.(I opened it with notepad++)
Btw, I'm using code::blocks17.12.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{ ofstream out("file1");
int i;
ifstream in;
if(!out){cerr << "create file error!\n"; return 1;}
for(i = 1; i<=10; ++i) out << i <<' ';
/*if I remove (<<' ') here, nothing was pirnted on screen. */
out.close();
in.open("file1");
if(!in){cerr << "open file error!\n"; return 1;}
while(in >> i) cout<< i << ' ';
in.close();
return 0;
}
If you write 1, 3 and 8 to a file without spaces then you get 138 how do you now want to figure out that it was not 138 that was written?
The input stream needs some kind of indication of how the numbers are separated.
If you want to know why they decided that writing a number does not automatically add a space, that is because it is not always the desired behavior.
And as Martin Heralecký correctly mentions. in >> i does not read in anything because without spaces 12345678910 is written to the file, which is most certainly out of the range of an int only your setup.
The actual size of an int is platform-dependent but you should not expect that it can store numbers larger than 2147483647.
More details about the Fundamental types: Properties

how to open and read a binary file in C++ by a given bin file?

Is there anyone could help me to check where I did wrong? Or explain why? I am a beginner and I tried my best to open the binary file. But it just runs out "file is open" "0". Nothing came out.
The objective:
The Count3s program opens a binary file containing 32-bit integers (ints). Your program will count the number of occurrences of the value 3 in this file of numbers. Your objective is to learn about opening and accessing files and apply your knowledge of control structures. The name of the file containing data used by the program is "threesData.bin".
my code as below, please help me if you know it. Thank you in advance!
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int count=0 ;
ifstream myfile;
myfile.open( "threesData.bin", ios::in | ios :: binary | ios::ate);
if (myfile)
{
cout << "file is open " << endl;
cout << count << endl; }
else
cout << "cannot open it" << endl;
return 0;
}
First of all you should read from file opened in binary mode with
myfile.read (buffer,length);
where buffer should be defined as
int data;
and used as
myfile.read (&data,sizeof(int));
The second important point is reading from file for more than one number - you need loop that is controled by condition that check stream. For example:
while (myfile.good() && !myfile.eof())
{
// read data
// then check and count value
}
And the last thing, you should close file, that was successfully oppened, after you finished reading:
myfile.open( "threesData.bin", ios::binary);
if (myfile)
{
while (myfile.good() && !myfile.eof())
{
// read data
// then check and count value
}
myfile.close();
// output results
}
And some additinal tips:
1) int is not always 32-bit type, so consider using int32_t from <cstdint>; and if your data has more than 1 byte, may be byte order is important, but it was not mentioned in the task description
2) read allows reading more than one data object per one call, but in that case you should read to array instead of one variable
3) read and try examples from references and other available resources like this.

find word in a text in C++ and print some next specific lines

I wrote a code in C++ that writes a .txt file.
Then I want to open the code again and give some information, so I can get a new text depending on what I gave as an input.
For example I want to give the name of a month, and print in another .txt file all the lines that came after the word "November".
I found some solutions, but none of them worked for me!
One solution that I found on stack overflow is the following:
void Keyword(ifstream & stream, string token) {
string line;
while (getline(stream, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
}
}
cout << token << " not found" << endl;
}
I can't print the next lines with the code above.
Any suggestion would be helpful!
Thanks!
If you want to perform operations on files such as 'Read' and/or 'Write',you might want to search on the net(or if you have a C++ book) on topics such as "File I/O operations using C++". Anyways moving on, C++ has 2 basic classes to handle files which are ifstream and ofstream. And to use them you have to include ethier the header fstream(i.e #include<fstream>) or include them separately as #include<ifstream> and #include<ofstream>. ifstream is basically used for all input operations such as reading files etc. Similarly ofstream is used for all output operations such as writing data to files.
You can open a file and write data to it by doing the following,
ofstream myFile("filename");// Create an instance of ofstream and open file for writing data
and to write data to the file use the << operator like below,
myFile<<data;
Similarly, You can open a file and read data as follows,
ifstream myFile("filename");//Create an instance of ifstream and open file to read data
and to read data from the file use the >> operator as shown below,
myFile>>data;
You can also open a file using the method void open(const char *filename, ios::openmode mode); as shown below,
//Writing only
ofstream outFile;
outFile.open("filename.txt",ios::out);
//Reading only
ifstream inFile;
inFile.open("filename.txt",ios::in);
//For reading and writing
fstream file;
file.open("filename.txt",ios::in|ios::out);
//For closing File
outFile.close();
//or
inFile.close();
//or
file.close();
Note the open() method takes various flags such as ios::in for reading mode, ios::out for writing mode, ios::app for adding data to the end etc.
All of these can also combined by using the bit OR operator | as shown below,
outFile.open("filename.txt",ios::out|ios::app);
There is a lot more in IO. I just covered the things required to start.
Here is the solution to your problem. Try to understand it.
#include<iostream>
#include<fstream>
#include<cstring>
using namespace std;
int main()
{
ofstream outFile;
ifstream inFile;
char fileName[10],data[50];
int noLines;
cout<<"Enter Month:"<<endl;
cin>>fileName;
cout<<"Enter Number of lines you want to enter:"<<endl;
cin>>noLines;
outFile.open(fileName,ios::out);
cout<<fileName<<"(Enter Data):";
for(int i=0;i<=noLines;i++)
{
cin.getline(data,50);
outFile<<data<<endl;
}
outFile.close();
cout<<"Openening "<<fileName<<" :"<<endl;
inFile.open(fileName,ios::in);
for(int i=0 ;i<=noLines ;i++)
{
inFile.getline(data,50);
cout<<data<<endl;
}
inFile.close();
return 0;
}
OP has found most of the solution already:
string line;
while (getline(stream, line)) {
if (line.find(token) != string::npos) {
cout << line << endl;
}
}
cout << token << " not found" << endl;
But this only prints the lines with the keyword. And always prints the "not found" message. Ooops.
Instead I pitch:
string line;
bool found = false;
while (!found && getline(stream, line))
{ // search for keyword
if (line.find(token) != string::npos)
{
found = true; // found keyword. Stop looking
}
}
if (found)
{ // print out all remaining lines in the file
while (getline(stream, line))
{
cout << line << endl;
}
}
else
{
cout << token << " not found" << endl;
}
The above splits the finding of the token and the printing of the remaining file into two stages for readability. It can be compressed into one loop, but two things make this a sucker bet:
this program will be IO bound. It will spend the vast majority of its time reading the file, so little tweaks that do not address getting the file into memory are wasted time.
combining the loops would require the addition of logic to the loop that would, over along run, dwarf the minuscule cost of switching loops.
Try this:
http://www.cplusplus.com/doc/tutorial/files/
and this:
http://www.cplusplus.com/forum/beginner/14975/
It's about reading and writing files in c++ and about searching in files.

How to write to middle of a file in C++?

I think this should be quite simple, but my googling didn't help so far... I need to write to an existing file in C++, but not necessarily at the end of the file.
I know that when I just want to append text to my file, I can pass the flag ios:app when calling open on my stream object. However, this only let's me write to the very end of the file, but not into its middle.
I made a short program to illustrate the issue:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
string path = "../test.csv";
fstream file;
file.open(path); // ios::in and ios::out by default
const int rows = 100;
for (int i = 0; i < rows; i++) {
file << i << "\n";
}
string line;
while (getline(file, line)) {
cout << "line: " << line << endl; // here I would like to append more text to certain rows
}
file.close();
}
You cannot insert in the middle of the file. You have to copy the old file to a new file and insert whatever you want in the middle during copying to the new file.
Otherwise, if you intend to overwrite data/lines in the existing file, that is possible by using std::ostream::seekp() to identify the position within the file.
You could write to the end and swap lines until it ends up in the right position.
Here's what I had to do.
Here's the test.txt file before:
12345678
12345678
12345678
12345678
12345678
Here's a sample of my program
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
fstream& goToLine(fstream& file, int line){
int charInLine = 10; //number of characters in each line + 2
//this file has 8 characters per line
int pos = (line-1)*charInLine;
file.seekg(pos);
file.seekp(pos);
return file;
}
fstream& swapLines(fstream& file, int firstLine, int secondLine){
string firstStr, secondStr;
goToLine(file,firstLine);
getline(file,firstStr);
goToLine(file,secondLine);
getline(file,secondStr);
goToLine(file,firstLine);
file.write(secondStr.c_str(),8); //Make sure there are 8 chars per line
goToLine(file,secondLine);
file.write(firstStr.c_str(),8);
return file;
}
int main(){
fstream file;
int numLines = 5; //number of lines in the file
//open file once to write to the end
file.open("test.txt",ios::app);
if(file.is_open()){
file<<"someText\n"; //Write your line to the end of the file.
file.close();
}
//open file again without the ios::app flag
file.open("test.txt");
if(file.is_open()){
for(int i=numLines+1;i>3;i--){ //Move someText\n to line 3
swapLines(file,i-1,i);
}
file.close();
}
return 0;
}
Here's the test.txt file after:
12345678
12345678
someText
12345678
12345678
12345678
I hope this helps!
Based on my basic knowledge of Operating systems, I would say it is not possible.
I mean it is not impossible to make an OS that can allow such functionality with current storage technologies, but doing so would always lead to wastage of space in segments.
But I am not aware of any technology that can allow that. Although some cloud-based DataBases do use such kinds of functionally (like inserting content in middle of a file), but they are made specifically for that DBMS software, with very specifically targeted hardware, and they may also have some custom-built kernels to perform such tasks.

C++ text decoder only taking one line from a text file

Im working on a two part program that uses an encoder do encode a text file then a decoder to decode the text file. However i cannot get my decoder to read the whole text file it just reads the first line. How do i fix this, ive played around with the loops but it is not helping me.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ifstream fin;
ofstream fout;
string lineFromFile;
fin.open("secret.txt");
if (!fin.good()) throw "I/O error";
fout.open("secret.txt", ios::app);
if (!fout.good()) throw "I/O error";
while (fin.good())
{
getline(fin, lineFromFile);
for (int i = 0; i < lineFromFile.length(); i++) // for each char in the string...
lineFromFile[i]--; // bump the ASCII code by 1
fout << lineFromFile << endl;
}//while
fin.close();
fout.close();
return 0;
}
You are closing the stream in the first iteration (i.e., after reading the first line). Then you open the output stream to write the first line. Only then do you reach the end of the while-loop, at which time fin.good() cannot be true anymore since you closed fin.
The loop should contain only the reading and writing. Opening done before the loop, closing done after.
Additional suggestion: Use proper indenting, it helps understanding the control flow.
I think the problem might be that you are reading and writing from the same file: secret.txt. I do not know what the expected behaviour is but when I ran the code it was infinite, which makes some sense as you are appending.
Try changing the ouput stream, fout, to a different file name.
The while loop that currently processes the file will process a final invalid read as you do not check if getline() was successful until the loop condition. I would suggest changing to:
for (;;)
{
getline(fin, lineFromFile);
if (!fin.good())
{
break;
}
for (int i = 0; i < lineFromFile.length(); i++)
lineFromFile[i]--;
fout << lineFromFile << endl;
}
Perhaps that because another file handle,fout, accesses the file to which fin is tied, fin is closed as a side-effect. Either that, or because fout appends to the file, the file pointer is pointed to the end of the file, and so because there is no more input to read, the loop ends.
(These are hypotheses; I am not familiar enough with the specifics of C++ I.O. to conclusively say what is happening.)
If you are supposed to replace the original file with an encoded version, I recommend setting the file tied to fout to a temporary file for the duration of your code above, closing both fin and fout, and then copying the file associated with fout over the file associated with fin.
Otherwise, just tie fout to a different filename than fin, such as "encoded.txt".