How to open file correctly? - c++

Lets assume we have INPUT.TXT file with the following content:
-
-- --
Here we have 16 characters: 5 (-) and 11 ( ). But when I run this code
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ifstream input("INPUT.TXT", ios::ate | ios::binary);
cout << input.tellg(); //returns the number of characters in file
return 0;
}
I get as result 13. I realized that this is due to the fact that the spaces on the first line after the character (-) disappear. So how can I open and read this file so that these spaces do not disappear?

Are you using any kind of advanced text editor that edits or beautify your texts at the time of saving it? I've run the same code on my device and I got the perfect output.
But I tried to save INPUT.TXT using Code::Blocks first. And I found out that Code::Blocks used to remove the trailing spaces during saving.
Use a simple editor that doesn't manipulate your data.

Related

Why is this not working? (Trying to convert a text file into a binary file)

#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<algorithm>
#include <sstream>
#include<iomanip>
using namespace std;
const string binaryfile = ".../binaryfile.dat";
void to_binary(const string& filename)
{
ifstream ist(filename);
ofstream ost(binaryfile, ios::binary);
char ch;
while (ist.get(ch))
{
ost.write((char*)&ch, sizeof(char));
}
}
int main()
{
cout << "Enter input file name:\n";
string ifile;
cin >> ifile;
to_binary(ifile);
}
This seems like it should be working to me but it doesn't? I give input a path to some file on my desktop and then call the function but it's just writing the normal text?
The file I'm giving as input contains this:
test file idk what to put here but yeah
Then I run this and binaryfile.dat gets the exact same text just normal text
binaryfile.dat
Does anyone know what I'm doing wrong? I open ost in binary mode, then get the address of each character I extract from ist, get 1 byte from it and write it to the binary file what's making this output normal text to it..?
Edit : Tried this with an int and it worked I got what I expected: This is what I expected
A file that obviously a human can't read why does it work with ints and not chars?
This is the code I used:
int main()
{
int a = 5;
ofstream out("ItemData.dat", ios::binary);
out.write((char*)&a, sizeof(int));
}
What exactly were you expecting to happen?
There is no such thing as a binary file. It's just a file.
A file is a series of bytes. Nothing more, nothing less.
A text file is a file where each byte "means" a character. For example, the byte value 01000001 means the capital letter A. When you open a file in Notepad, Notepad reads the bytes and displays the corresponding letters. If it sees the byte value 01000001 it displays the capital letter A.
Notepad has no idea whether the file "is a text file" or not. It just looks at the bytes and displays the letters. You can open any file in Notepad, such as an EXE file or a JPEG file, and whenever it happens to contain the byte value 01000001 it will display the capital letter A.
Your code reads bytes from a file in text mode and writes them in binary mode. So it makes a copy of the same file... except for the difference between text mode and binary mode.
So what is that difference? Well, the only difference is that text mode tries to "normalize" line endings. Windows has a tradition that the end of a line of text consists of bytes 00001101 and 00001010 in that order. C has a tradition that the end of a line of text is just the byte 00001010. Text mode does that conversion, so that you can read Windows text files in C.
If the file has the byte value 00001010 without a 00001101 before it, most text editors still display it as a line ending, but until Windows 10, Notepad didn't display it as a line ending. Now Notepad does that too. So you won't see the difference in a text editor. You can see the difference in a hex editor program, which directly shows you the bytes in a file (in hexadecimal). I recommend HxD if you are using Windows.
The main reason for opening binary files in binary mode is because if you open a binary file in text mode, the operating system will add or delete 00001101 bytes which will mess up your binary data. Opening the file in binary mode tells it to please not mess up your binary data.

Appending string in the middle of a text file

here is my code
#include <string>
#include <iostream>
#include <fstream>
int main(void){
fstream myfile2;
myfile2.open("test2.txt", ios::app);
string checkline;
getline(myfile2, checkline);
int razmer=checkline.length();
string balli="256";
myfile2.seekp(razmer);
myfile2<<balli;
}
test2.txt consists of 2 strings, so it is looks like
Ivanov
Petrov
I want to make from Ivanov -> Ivanov 256. With no touching 2nd string. But my code did not work at all. Thanks in advance.
There's no easy way to edit a text file. The usual solution is to read the whole source file into memory, make your modifications in memory, and then write out all of the file.
In your example where the file seems to be line-based, you could read it line by line and put the lines in a std::vector. Edit the line you want to edit, then loop over the vector and write out the lines.
Note: When writing the file, you open it in write mode, so the file is recreated and looses all old contents.

Can't get a simple ifstream to work in Visual Studio Express

I am trying to learn C++ and am on the file input/output section. I've hit a brick wall because my test application just plainly isn't working in Visual Studio Express 2012. Here is my code:
// ConsoleApp03.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
ifstream file_reader;
file_reader.open("C:\temp.txt");
// Test to see if the file was opened
if (!file_reader.is_open() ) {
cout << "Could not open file!" << endl;
return 255;
}
string line;
// Read the entire file and display it to the user;
while (getline(file_reader,line)) {
cout << line << endl;
}
// Close the file
file_reader.close();
return 0;
}
Every time I run this, I get "Could not open file!". I have verified that the file being opened does exist, and I have sufficient permission to read. I have tried other text files, including in other different locations like my documents folder, but the result is always the same. My text file is very simple and only contains two lines of text. I am abel to open this file in Notepad++, and the file has no special attributes (system, Read only, etc). I have even tried converting the file to/from ANSI and UTF-8 with no luck.
I have looked at other problems similar to what I have here, but these don't seem to be applicable to me (e.g.: ifstream::open not working in Visual Studio debug mode and ifstream failing to open)
Just to show how simple the text file is, here is me typing it from the command prompt:
C:\>type C:\temp.txt
Hi
There
This may or may not fix your problem, but \ followed by char is an escape sequence. So your file path is actually invalid. Try
file_reader.open("C:\\temp.txt");
The \t actually means tab. See here.

Using getline on html file

I have this assignment to search for certian info in a html file and put the result into text file. I wanted to do it using getline, but somehow it's not working. I have no problems with using getline on text file so I assumed that you cannot use getline on html file. Is that assumption right? How can I convert such file into a text file? Or maybe there is a better/easier solution?Thanks.
Here is the code:(the names of the variables are not in english, I hope it's not a problem)
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
string nazwa_wejsciowego;
string roboczy;
ifstream html;
ifstream txt("wynik.txt");
int main()
{
cout<<"Podaj nazwę pliku html, z ktorego odczytane maja zostac dane."<<endl;
cin>>nazwa_wejsciowego;
ifstream html(nazwa_wejsciowego, ios::app); //opening the file
if(!html){
cout<<"Otwarcie pliku "<<nazwa_wejsciowego<<" nie powiodlo sie."<<endl;
system("pause");}
//checking if it opende properly
getline(html, roboczy);
cout<<roboczy<<endl;
return 0;}
No, the assumption is not right. HTML is text; the fact that it is in a structured format that can be parsed by a computer to render a webpage is not relevant to read individual characters in the file.
getline may be a suitable approach though, as Steve points out in comments, some HTML pages are "minified" (they have unnecessary whitespace removed to save space and make code harder to copy) and, in such a case, you may end up with just one really big line. It may therefore be more convenient to read in chunks of bytes.

Reading ISO-8859 type file containing special characters such as é in C++

I'm trying to read a file which is encoded in ISO-8859(ansi), and it contains some west European characters such as "é".
When I try to read the file and output the result, all the special characters appear as �, whereas normal alphabets appear correctly.
If I convert the file to utf-8 format and then do the same job, everything works perfectly.
Does anyone have any idea to solve this problem? I tried to use wifstream and wstring instead of ifstream and string but didn't help much.
Here's my sample code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream myFS;
myFS.open("test.txt", ios::in);
string myString;
if(myFS.is_open()){
while(myFS >> myString)
cout << myString << endl;
}
myFS.close();
return 0;
}
test.txt (ISO-8859-15 format) contains:
abcd éfg
result:
abcd
�fg
Any advice will be appreciated.
Thank you in advance!
+)
forgot to mention my system environment.
I'm using ubuntu 10.10(Maverick) console with g++ ver 4.4.5
Thanks!
Your console is set to use UTF-8, so when you just dump the file in ISO-8859-15 to the console using cout, it shows the wrong letters. Letters with ascii code <128 are the same in both encodings, which means all those characters will appear correctly on your screen.
The output from the program is actually correct, it's just your console that's not set to display the output correctly.
I'd also recommend using ios::binary on files that aren't all ascii, or you may have problems on other platforms later.