Unable to use program to access a File - c++

I am using a Macbook.
I have created a file using text edit, and have written the numbers 3 and 4 on it with a space in between. I saved this file called 'mydata', which then produced 'mydata.rtf'. I then changed this files name to 'mydata.txt'.
I have then created this program to open this file, and then print the values within the file 'mydata.txt'.
However, it is printing the values: a = 446595126, b = 32767.
Could someone please explain why this program doesn't print 3 and 4.
Thank you.
#include<stdio.h>
int main(void)
{
int a, b;
FILE *fptr1;
fptr1 = fopen ( "mydata.txt", "r" );
if (fptr1 == NULL )
{
printf("FILE mydata.txt did not open\n");
}
else
{
fscanf(fptr1,"%d%d",&a,&b);
printf("a = %d, b = %d\n",a,b);
}
fclose(fptr1);
return 0;
}

Your file is RTF (Rich Text Format), no matter the extension it has: you've simply renamed it, not converted to a different format.
The reason why you see those values is because the first characters of your file does not correspond with the numbers you entered in the editor but with the first bytes of the RTF format.
As a solution, open the file with TextEdit again and save it with a plain text format instead. You can take a look at this post too.
In general, avoid using editors that supports rich format (TextEdit, Word, Pages) for creating plain text files. Instead, use other ones like BBEdit, TextWrangler (although I think it's discontinued), emacs, Atom, vim, nano, etc.

the reason behind it is you have included space between the two numbers and a space is a character which has ascii value of 32..
so try ommiting space while reading number from file.
This may work :-)

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.

C++ Null characters in string?

I want to read a txt file and convert two cells from each line to floats.
If I first run:
someString = someString.substr(1, tempLine.size());
And then:
std::stof(someString)
it only converts the first number in 'someString' to a number. The rest of the string is lost.
When I handled the string in my IDE I noticed that copying it and pasting it inside quotation marks gives me "\u00005\u00007\u0000.\u00007\u00001\u00007\u00007\u0000" and not 57.7177.
If I instead do:
std::string someOtherString = "57.7177"
std::stof(someOtherString)
I get 57.7177.
Minimal working example is:
int main() {
std::string someString = "\u00005\u00007\u0000.\u00007\u00001\u00007\u00007\u0000";
float someFloat = std::stof(someString);
return 0;
}
Same problem occurs using both UTF-8 and -16 encoding.
What is happening and what should I do differently? Should I remove the null-characters somehow?
"I want to read a txt file"
What is the encoding of the text file? "Text" is not a encoding. What I suspect is happening is that you wrote code that reads in the file as either UTF8 or Windows-1250 encoding, and stored it in a std::string. From the bytes, I can see that the file is actually UTF16BE, and so you need to read into a std::u16string. If your program will only ever run on Windows, then you can get by with a std::wstring.
You probably have followup questions, but your original question is vague enough that I can't predict what those questions would be.

embedding a text file in an exe which can be accessed using fopen

I would like to embed a text file with some data into my program.
let's call it "data.txt".
This text file is usually loaded with a function which requires the text file's file name as input and is eventually opened using a fopen() call... some something to the lines of
FILE* name = fopen("data.txt");
I can't really change this function and I would like the routine to open this same file every time it runs. I've seen people ask about embedding the file as a header but it seems that I wouldn't be able to call fopen() on a file that I embed into the header.
So my question is: is there a way to embed a text file as a callable file/variable to fopen()?
I am using VS2008.
Yes and No. The easiest way is to transform the content of the text file into an initialized array.
char data_txt[] = {
'd','a','t','a',' ','g','o','e','s',' ','h','e','r','e', //....
};
This transformation is easily done with a small perl script or even a small C program. You then compile and link the resulting module into your program.
An old trick to make this easier to manage with a Makefile is to make the script transform its data into the body of the initializer and write it to a file without the surrounding variable declaration or even the curly braces. If data.txt is transformed to data.inc, then it is used like so:
char data_txt[] = {
#include "data.inc"
};
Update
On many platforms, it is possible to append arbitrary data to the executable file itself. The trick then is to find it at run time. On platforms where this is possible, there will be file header information for the executable that indicates the length of the executable image. That can be used to compute an offset to use with fseek() after you have opened the executable file for reading. That is harder to do in a portable way, since it may not even be possible to learn the actual file name of your executable image at run time in a portable way. (Hint, argv[0] is not required to point to the actual program.)
If you cannot avoid the call to fopen(), then you can still use this trick to keep a copy of the content of data.txt, and put it back in a file at run time. You could even be clever and only write the file if it is missing....
If you can drop the call to fopen() but still need a FILE * pointing at the data, then this is likely possible if you are willing to play fast and loose with your C runtime library's implementation of stdio. In the GNU version of libc, functions like sprintf() and sscanf() are actually implemented by creating a "real enough" FILE * that can be passed to a common implementation (vfprintf() and vfscanf(), IIRC). That faked FILE is marked as buffered, and points its buffer to the users's buffer. Some magic is used to make sure the rest of stdio doesn't do anything stupid.
For any kind of file, base on RBerteig anwser you could do something simple as this with python:
This program will generate a text.txt.c file that can be compiled and linked to your code, to embed any text or binary file directly to your exe and read it directly from a variable:
import struct; # Needed to convert string to byte
f = open("text.txt","rb") # Open the file in read binary mode
s = "unsigned char text_txt_data[] = {"
b = f.read(1) # Read one byte from the stream
db = struct.unpack("b",b)[0] # Transform it to byte
h = hex(db) # Generate hexadecimal string
s = s + h; # Add it to the final code
b = f.read(1) # Read one byte from the stream
while b != "":
s = s + "," # Add a coma to separate the array
db = struct.unpack("b",b)[0] # Transform it to byte
h = hex(db) # Generate hexadecimal string
s = s + h; # Add it to the final code
b = f.read(1) # Read one byte from the stream
s = s + "};" # Close the bracktes
f.close() # Close the file
# Write the resultan code to a file that can be compiled
fw = open("text.txt.c","w");
fw.write(s);
fw.close();
Will generate something like
unsigned char text_txt_data[] = {0x52,0x61,0x6e,0x64,0x6f,0x6d,0x20,0x6e,0x75...
You can latter use your data in another c file using the variable with a code like this:
extern unsigned char text_txt_data[];
Right now I cant think of two ways to converting it to readable text. Using memory streams or converting it to a c-string.

C++ ofstream is changing output format randomly?

I have a function that is writing to a .txt file.
ofstream fichier("C:\\users\\me\\Desktop\\test.txt", ios::app);
then :
fichier << "some text here";
The text i'm writing is a log file containing the history of my application changes.
As i'm french, i'm writing characters (latin ?) like "ê" or "ë". This works randomly...At first i get the correct format in notepad then when i append some others characters, it switches to another format so "ê" becomes "ê" and i don't understand why.
(In fact i can't even get "¨" to be compiled by code::blocks because it is a "multi characters constant")
What should i do ?
Thanks by advance.

Difference between files written in binary and text mode

What translation occurs when writing to a file that was opened in text mode that does not occur in binary mode? Specifically in MS Visual C.
unsigned char buffer[256];
for (int i = 0; i < 256; i++) buffer[i]=i;
int size = 1;
int count = 256;
Binary mode:
FILE *fp_binary = fopen(filename, "wb");
fwrite(buffer, size, count, fp_binary);
Versus text mode:
FILE *fp_text = fopen(filename, "wt");
fwrite(buffer, size, count, fp_text);
I believe that most platforms will ignore the "t" option or the "text-mode" option when dealing with streams. On windows, however, this is not the case. If you take a look at the description of the fopen() function at: MSDN, you will see that specifying the "t" option will have the following effect:
line feeds ('\n') will be translated to '\r\n" sequences on output
carriage return/line feed sequences will be translated to line feeds on input.
If the file is opened in append mode, the end of the file will be examined for a ctrl-z character (character 26) and that character removed, if possible. It will also interpret the presence of that character as being the end of file. This is an unfortunate holdover from the days of CPM (something about the sins of the parents being visited upon their children up to the 3rd or 4th generation). Contrary to previously stated opinion, the ctrl-z character will not be appended.
In text mode, a newline "\n" may be converted to a carriage return + newline "\r\n"
Usually you'll want to open in binary mode. Trying to read any binary data in text mode won't work, it will be corrupted. You can read text ok in binary mode though - it just won't do automatic translations of "\n" to "\r\n".
See fopen
Additionally, when you fopen a file with "rt" the input is terminated on a Crtl-Z character.
Another difference is when using fseek
If the stream is open in binary mode, the new position is exactly offset bytes measured from the beginning of the file if origin is SEEK_SET, from the current file position if origin is SEEK_CUR, and from the end of the file if origin is SEEK_END. Some binary streams may not support the SEEK_END.
If the stream is open in text mode, the only supported values for offset are zero (which works with any origin) and a value returned by an earlier call to std::ftell on a stream associated with the same file (which only works with origin of SEEK_SET.
Even though this question was already answered and clearly explained, I think it would be interesting to show the main issue (translation between \n and \r\n) with a simple code example. Note that I'm not addressing the issue of the Crtl-Z character at the end of the file.
#include <stdio.h>
#include <string.h>
int main() {
FILE *f;
char string[] = "A\nB";
int len;
len = strlen(string);
printf("As you'd expect string has %d characters... ", len); /* prints 3*/
f = fopen("test.txt", "w"); /* Text mode */
fwrite(string, 1, len, f); /* On windows "A\r\nB" is writen */
printf ("but %ld bytes were writen to file", ftell(f)); /* prints 4 on Windows, 3 on Linux*/
fclose(f);
return 0;
}
If you execute the program on Windows, you will see the following message printed:
As you'd expect string has 3 characters... but 4 bytes were writen to file
Of course you can also open the file with a text editor like Notepad++ and see yourself the characters:
The inverse conversion is performed on Windows when reading the file in text mode.
We had an interesting problem with opening files in text mode where the files had a mixture of line ending characters:
1\n\r
2\n\r
3\n
4\n\r
5\n\r
Our requirement is that we can store our current position in the file (we used fgetpos), close the file and then later to reopen the file and seek to that position (we used fsetpos).
However, where a file has mixtures of line endings then this process failed to seek to the actual same position. In our case (our tool parses C++), we were re-reading parts of the file we'd already seen.
Go with binary - then you can control exactly what is read and written from the file.
In 'w' mode, the file is opened in write mode and the basic coding is 'utf-8'
in 'wb' mode, the file is opened in write -binary mode and it is resposible for writing other special characters and the encoding may be 'utf-16le' or others