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

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))

Related

C++: Getline stops reading at first whitespace

Basically my issue is that I'm trying to read in data from a .txt file that's full of numbers and comments and store each line into a string vector, but my getline function stops reading at the first whitespace character so a comment like (* comment *) gets broken up into
str[0] = "(*";
str[1] = "comment";
str[2] = "*)";
This is what my codeblock for the getline function looks like:
int main() {
string line;
string fileName;
cout << "Enter the name of the file to be read: ";
cin >> fileName;
ifstream inFile{fileName};
istream_iterator<string> infile_begin {inFile};
istream_iterator<string> eof{};
vector<string> data {infile_begin, eof};
while (getline(inFile, line))
{
data.push_back(line);
}
And this is what the .txt file looks like:
101481
10974
1013
(* comment *) 0
28292
35040
35372
0000
7155
7284
96110
26175
I can't figure out why it's not reading the whole line.
This is for the very simple reason that your code is not using std::getline to read the input file.
If you look at your code very carefully, you will see that before you even get to that point, your code constructs an istream_iterator<string> on the file, and by passing it, and the ending istream_iterator<string> value to the vector's constructor, this effectively swallows the entire file, one whitespace-delimited word at a time, into the vector.
And by the time things get around to the getline loop, the entire file has already been read, and the loop does absolutely nothing. Your getline isn't really doing anything, with the current state of affairs.
Get rid of that stuff that involves istream_iterators, completely, and simply let getline do the job it was intended for.

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)

Cannot read binary file with bracket characters in 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.

Problems using getline()

I'm running out of hair to pull out, so I thought maybe someone here could help me with this frustration.
I'm trying to read a file line by line, which seems simple enough, using getline(). Problem is, my code seems to keep ignoring the \n, and putting the entire file into one string, which is problematic to say the least.
void MakeRandomLayout(int rows, int cols)
{
string fiveByFive = "cubes25.txt";
string fourByFour = "cubes16.txt";
ifstream infile;
while (true) {
infile.open(fourByFour.c_str());
if (infile.fail()) {
infile.clear();
cout << "No such file found";
} else {
break;
}
}
Vector<string> cubes;
string cube;
while (std::getline(infile, cube)) {
cubes.add(cube);
}
}
Edits: Running OSX 10.7.
The infinite loop for the file is unfinished, will eventually ask for a file.
No luck with extended getline() version, tried that earlier.
Same system for dev and build/run.
The text file i'm reading in looks as follows:
AAEEGN
ABBJOO
ACHOPS
AFFKPS
AOOTTW
CIMOTU
DEILRX
DELRVY
DISTTY
EEGHNW
EEINSU
EHRTVW
EIOSST
ELRTTY
HIMNQU
HLNNRZ
Each string is on a new line in the file. The second one that I'm not reading in is the same but 25 lines instead of 16
Mac software recognizes either '\r' or '\n' as line-endings, for backward compatibility with Mac OS Classic. Make sure that your text editor hasn't put '\r' line endings in your file when your processing code is expecting '\n' (and verify that the '\n' characters you think are in the middle of the string aren't in fact '\r' instead.
I suspect that you are failing to display the contents of Vector correctly. When you dump the Vector, do you print a \n after each entry? You should, because getline discards the newlines on input.
FYI: the typical pattern for reading line-by-line is this:
Vector<string> cubes;
string cube;
while(std::getline(infile, cube)) {
cubes.add(cube);
}
Note that this will discard the newlines, but will put one line per entry in Vector.
EDIT: For whatever it is worth, if you were using an std::vector, you could slurp the file in thusly:
std::ifstream ifile(av[1]);
std::vector<std::string> v(
(std::istream_iterator<std::string>(ifile)),
std::istream_iterator<std::string>());

getline() reads an extra line

ifstream file("file.txt");
if(file.fail())
{
cout<<"Could not open the file";
exit(1);
}
else
{
while(file)
{
file.getline(line[l],80);
cout<<line[l++]<<"\n";
}
}
I am using a two dimensional character array to keep the text (more than one line) read from a file to count the number of lines and words in the file but the problem is that getline always reads an extra line.
Your code as I'm writing this:
ifstream file("file.txt");
if(file.fail())
{
cout<<"Could not open the file";
exit(1);
}
else
{
while(file)
{
file.getline(line[l],80);
cout<<line[l++]<<"\n";
}
}
The first time getline fails, you still increment the line counter and output the (non-existing) line.
Always check for an error.
extra advice: use std::string from the <string> header, and use its getline function.
cheers & hth.
The problem is when you're at the end of the file the test on file will still succeed because you have not yet read past the end of file. So you need to test the return from getline() as well.
Since you need to test the return from getline() to see if it succeeded, you may as well put it right in the while loop:
while (file.getline(line[l], 80))
cout << line[l++] << "\n";
This way you don't need a separate test on file and getline().
This will solve your problem:
ifstream file("file.txt");
if(!file.good())
{
cout<<"Could not open the file";
exit(1);
}
else
{
while(file)
{
file.getline(line[l],80);
if(!file.eof())
cout<<line[l++]<<"\n";
}
}
Its more robust
Does the file end with a newline? If it does, the EOF flag will not be triggered until one extra loop passes. For example, if the file is
abc\n
def\n
Then the loop will be run 3 times, the first time it will get abc, the second time it will get def and the third time it will get nothing. That's probably why you see an additional line.
Try checking the failbit on the stream AFTER the getline.
Only do the cout if file.good() is true. The extra line you're seeing comes from the last call to file.getline() which reads past the end of the file.