Cannot read binary file with bracket characters in C++ - c++

I have function which reads a File & checks its contents.
The file contains some binary content along with non alphabet characters like (), =, divided by symbol, etc.
The function which does the reading is:
int FindMyWord(const char *fileName)
{
ifstream myFile (fileName);
if(!myFile)
return false;
string wordSearch = "MyWord";
string line;
int result = 0;
while(getline(myFile, line))
{
if(line.find(wordSearch) != string::npos)
result++;
}
//if(!myFile.eof() || !myFile)
if(!myFile)
printf("Problem Reading the File: %s\n", (const char *)fileName);
myFile.close();
return result;
}
I am having these 2 problems:
If a line contains binary characters then it is not reading the complete line, just reading the first word (atleast that's what I am observing by opening the file in VS2010).
When it encounters the character ( for the beginning of a line the while loop is terminated & the printf() is printed.
If string::getline() cannot read such characters then what is the solution?
Thank You.
UPDATE: The Image of some of the binary data in the file:

A text input stream should not fail on a bracket character.
If you actually need a binary stream, use ifstream(filename, std::ios::binary)

Have a read through the std::getline docs at cppreference.com. You should check the failbit on the stream if you have any odd behaviour.

Related

C++, write from file into map

im just new at c++ and I try to read from a file and write the content into a map<string, float>.
But only the first element of my file gets mapped and i cant figuer out why.
The file looks like this:
E:16.93
N:10.53
I:8.02
...
And the code i got for this part so far:
std::map<char, float> frequenciesM;
fstream frequencieFile("frequencies.txt", std::ios::in);
if(!frequencieFile){
cout << "No such File!";
}else{
std::string line;
char ch;
std::string sub;
float fl;
while (std::getline(frequencieFile, line, '\0')) {
ch = line[0];
sub = line.substr(2);
fl = std::stof(sub);
frequenciesM[ch] = fl;
}
}
When i try to print out the size and content of my map, this is what i get:
Size: 1
E: 16.93
Thx for any help and suggestions!
You are telling getline() to read until a '\0' (nul) character is encountered, but there is no such character in your file, so the entire file gets read into the string on the 1st call, and then you extract only the 1st set of values from the string, discarding the rest of the data.
To read the file line-by-line, you need to change the 3rd parameter of getline() to '\n' instead:
while (std::getline(frequencieFile, line, '\n'))
Or, just drop the 3rd parameter entirely since '\n' is the default delimiter:
while (std::getline(frequencieFile, line))

c++ reading file with \ inside the text

I need help with a small problem.
I wrote a small program that reads every line of the text inside a .rd file to a string. But inside the text are some \ and when I output the strings the program think that the \ are escape characters.
What can I do to get the original text?
The Program run without an error.
Here is a small snippet of my code:
string find="something";
string replace="something2";
string line="";
fstream myfile;
myfile.open ("file.rb");
if (myfile.is_open())
{
while (getline(myfile,line))
{
cout << line << '\n';
if(line == find)
{
myfile << replace;
}
else
{
myfile << line;
}
}
myfile.close();
}
You should try using a unicode version of getline or you could try adding ios::binary to your stream constructor flags.
See this article for further info.
However, if you read in a string like "\0" from stdin or a file, it should be treated as two separate characters: '\' and '0'. There is no additional processing that you have to do.
Escaping characters is only used for string/character literals. That is to say, when you want to hard-code something into your source code.

File read and write while reading the file line by line

Program:
#include<iostream>
#include<fstream>
#include<stdio.h>
#include<string.h>
using namespace std;
int main()
{
FILE *f;
char* line;
size_t ln=100;
char* s;
line=new char[100];
s=new char[100];
cout<<"input key"<<endl;
cin>>s;
f=fopen("parvin.txt","r");
if(f==NULL)
{
cout<<" no file TO read so creating for writing "<<endl;
//return 0;
f=fopen("parvin.txt","w");
fputs(s,f);
fputc('\n',f);
}
else
{
while(! feof(f))
{
fgets(line,100,f);
cout<<line<<endl;
//if(!strncmp(line,s,strlen(line)-1))
if(strcmp(line,s)== 0 )
{
cout<<"duplicate found"<<endl;
fclose(f);
return 0;
}
}
fclose(f);
f=fopen("parvin.txt","a+");
fputs(s,f);
fputc('\n',f);
}
fclose(f);
}
Here the above program where I like to read an input string and write it into file provided the string is not present already in file.
take input string
open file in read mode.
if it is first time entry file will not be there if file pointer return NULL, create a file to write mode and write the
inputted string.
if file already there then read file line by line and compare with input string if match with any line then return and close.
other wise open the same file in write mode and write the inputted string.
But it is not working properly..
strcmp not executing properly.... with the duplicate entry also it
dont go into that loop of "duplicae found" .
please if anyone can help ...
The fgets:
fgets(line,100,f);
consumes the newline character from f and stores it in line. But s doesn't contain the newline character. So, the strcmp returns a non-zero number as the strings(s and f) are different.
Strip the newline character by using
line[strcspn(line, "\n")] = '\0';
just after the fgets. The strcspn function, in your case, returns the number of characters until a \n in line. If \n is not found in line, it returns the length of the string line(strlen(line)).
Also, read Why is while ( !feof (file) ) always wrong?. Replace
while(!feof(f))
with
while(fgets(line,100,f)) //Same as `while(fgets(line,100,f) != NULL)`
and don't forget to remove the fgets from the body of the loop to fix this issue.
Use
while(fgets(line,100,f)!=NULL)

Deleting from a certain point in a file to the end of the line?

I'm having some trouble with detecting two '//' as a char and then deleting from the first '/' till the end of the line (im guessing /n comes into use here).
{
ifstream infile;
char comment = '//';
infile.open("test3.cpp");
if (!infile)
{
cout << "Can't open input file\n";
exit(1);
}
char line;
while (!infile.eof())
{
infile.get(line);
if (line == comment)
{
cout << "found it" << endl;
}
}
return 0;
}
In the test3.cpp file there are three comments, so 3 lots of '//'. But I can't detect the double slash and can only detect a single / which will affect other parts of the c++ file as I only want to delete from the beginning of a comment to the end of the line?
I'm having some trouble with detecting two '//' as a char
That's because // is not a character. It is a sequence of two characters. A sequence of characters is known as a string. You can make string literals with double quotation marks: "//".
A simple solution is to compare the current input character from the stream to the first character of the string "//" which is '/'. If it matches, then compare the next character from the stream with the second character in the string that is searched for. If you find two '/' in a row, you have your match. Or you could be smart and read the entire line into a std::string and use the member functions to find it.
Also:
while (!infile.eof())
{
infile.get(line);
// using line without testing eof- and badbit
This piece of code is wrong. You test for eofbit before reading the stream and process the input.
And your choice of name for the line variable is a bit confusing since it doesn't contain the entire. line but just one character.

How to read content of the file and save it to string type variable? Why there is empty space?

This is how I get the name of the file from the command line and open a file and save the content of the file line by line to a string. All the procedures works fine except three empty spaces at the beginning of the file. Is anyone can say why these empty spaces occurred and how can I ignore them?
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
if(!fin.good()){
cout<<" = File does not exist ->> No File for reading\n";
exit(1);
}
string s;
while(!fin.eof()){
string tmp;
getline(fin,tmp);
s.append(tmp);
if(s[s.size()-1] == '.')
{
//Do nothing
}
else
{
s.append(" ");
}
cout<<s<<endl;
The most probable cause is that your file is encoded in something else than ASCII. It contains a bunch of unprintable bytes and the string you on the screen is the result of your terminal interpreting those bytes. To confirm this, print the size of s after the reading is done. It should be larger than the number of characters you see on the screen.
Other issues:
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
is quite an overzealous way to go about it. Just write ifstream fin(a.c_str());, or simply ifstream fin(a); in C++11.
Next,
while(!fin.eof()){
is almost surely a bug. eof() does not tell if you the next read will succeed, only whether the last one reached eof or not. Using it this way will tipically result in last line seemingly being read twice.
Always, always, check for success of a read operation before you use the result. That's idiomatically done by putting getline in the loop condition: while (getline(fin, tmp))