Are standard text files NULL-terminated? - c++

I am writing a C++ program that reads a file and then sends it to another class as a character array. Because character arrays only get passed by pointer, all size is lost.
The file it'll be reading will be a text file. Are text files null terminated?
Preferably I do not want to use a Vector as I really don't need any of it's features but the size of the array.

No.
Files have a known length, so they do not need any terminator byte.

no text files are not NULL terminated. You need to check for EOF (End Of File)
I think
cin.eof()
is what you are searching. It returns true if the end of file is reached.

No, they are not. But many C/C++ function to read strings from files appends zero termination to returned data.

use eof rather than finding null character ...
for example :
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream iFile("myfile.txt"); // myfile.txt has integers, one per line
while (!iFile.eof())
{
int x;
iFile >> x;
cerr << x << endl;
}
return 0;
}

Related

storing text to string from a file that contains spaces

So I've been doing algorithms in C++ for about 3 months now as a hobby. I've never had a problem I couldn't solve by googleing up until now. I'm trying to read from a text file that will be converted into a hash table, but when i try and capture the data from a file it ends at a space. here's the code
#include <iostream>
#include <fstream>
int main()
{
using namespace std;
ifstream file("this.hash");
file >> noskipws;
string thing;
file >> thing;
cout << thing << endl;
return 0;
}
I'm aware of the noskipws flag i just don't know how to properly implement it
When using the formatted input operator for std::string it always stops at what the stream considers to be whitespace. Using the std::locale's character classification facet std::ctype<char> you can redefine what space means. It's a bit involved, though.
If you want to read up to a specific separator, you can use std::getline(), possibly specifying the separator you are interested in, e.g.:
std::string value;
if (std::getline(in, value, ',')) { ... }
reads character until it finds a comma or the end of the file is reached and stores the characters up to the separator in value.
If you just want to read the entire file, one way to do is to use
std::ifstream in(file.c_str());
std::string all((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
I think the best tool for what you're trying to do is get, getline or read. Now those all use char buffers rather than std::strings, so need a bit more thought, but they're quite straightforward really. (edit: std::getline( file, string ), as pointed out by Dietmar Kühl, uses c++ strings rather than character buffers, so I would actually recommend that. Then you won't need to worry about maximum line lengths)
Here's an example which will loop through the entire file:
#include <iostream>
int main () {
char buffer[1024]; // line length is limited to 1023 bytes
std::ifstream file( "this.hash" );
while( file.good( ) ) {
file.getline( buffer, sizeof( buffer ) );
std::string line( buffer ); // convert to c++ string for convenience
// do something with the line
}
return 0;
}
(note that line length is limited to 1023 bytes, and if a line is longer it will be broken into 2 reads. When it's a true newline, you'll see a \n character at the end of the string)
Of course, if you a maximum length for your file in advance, you can just set the buffer accordingly and do away with the loop. If the buffer needs to be very big (more than a couple of kilobytes), you should probably use new char[size] and delete[] instead of the static array, to avoid stack overflows.
and here's a reference page: http://www.cplusplus.com/reference/fstream/ifstream/

Length of a char array

I have the code like this:
#include <iostream.h>
#include <fstream.h>
void main()
{
char dir[25], output[10],temp[10];
cout<<"Enter file: ";
cin.getline(dir,25); //like C:\input.txt
ifstream input(dir,ios::in);
input.getline(output,'\eof');
int num = sizeof(output);
ofstream out("D:\\size.txt",ios::out);
out<<num;
}
I want to print the length of the output. But it always returns the number 10 (the given length) even if the input file has only 2 letters ( Like just "ab"). I've also used strlen(output) but nothing changed. How do I only get the used length of array?
I'm using VS C++ 6.0
sizeof operator on array gives you size allocated for the array, which is 10.
You need to use strlen() to know length occupied inside the array, but you need to make sure the array is null terminated.
With C++ better alternative is to simple use: std::string instead of the character array. Then you can simply use std::string::size() to get the size.
sizeof always prints the defined size of an object based on its type, not anything like the length of a string.
At least by current standards, your code has some pretty serious problems. It looks like it was written for a 1993 compiler running on MS-DOS, or something on that order. With a current compiler, the C++ headers shouldn't have .h on the end, among other things.
#include <iostream>
#include <fstream>
#include <string>
int main() {
std::string dir, output, temp;
std::cout<<"Enter file: ";
std::getline(cin, dir); //like C:\input.txt
std::ifstream input(dir.c_str());
std::getline(input, output);
std::ofstream out("D:\\size.txt");
out<<output.size();
}
The getline that you are using is an unformatted input function so you can retrieve the number of characters extracted with input.gcount().
Note that \e is not a standard escape sequence and the character constant \eof almost certainly doesn't do what you think it does. If you don't want to recognise any delimiter you should use read, not getline, passing the size of your buffer so that you don't overflow it.

How to read a specific amount of characters from a text file

I tried to do it like this
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char b[2];
ifstream f("prad.txt");
f>>b ;
cout <<b;
return 0;
}
It should read 2 characters but it reads whole line. This worked on another language but doesn't work in C++ for some reason.
You can use read() to specify the number of characters to read:
char b[3] = "";
ifstream f("prad.txt");
f.read(b, sizeof(b) - 1); // Read one less that sizeof(b) to ensure null
cout << b; // terminated for use with cout.
This worked on another language but doesn't work in C++ for some
reason.
Some things change from language to language. In particular, in this case you've run afoul of the fact that in C++ pointers and arrays are scarcely different. That array gets passed to operator>> as a pointer to char, which is interpreted as a string pointer, so it does what it does to char buffers (to wit read until the width limit or end of line, whichever comes first). Your program ought to be crashing when that happens, since you're overflowing your buffer.
istream& get (char* s, streamsize n );
Extracts characters from the stream and stores them as a c-string into
the array beginning at s. Characters are extracted until either (n -
1) characters have been extracted or the delimiting character '\n' is
found. The extraction also stops if the end of file is reached in the
input sequence or if an error occurs during the input operation. If
the delimiting character is found, it is not extracted from the input
sequence and remains as the next character to be extracted. Use
getline if you want this character to be extracted (and discarded).
The ending null character that signals the end of a c-string is
automatically appended at the end of the content stored in s.

saving files in c++ at different full paths

I am writing a program in C++ which I need to save some .txt files to different locations as per the counter variable in program what should be the code? Please help
I know how to save file using full path
ofstream f;
f.open("c:\\user\\Desktop\\**data1**\\example.txt");
f.close();
I want "c:\user\Desktop\data*[CTR]*\filedata.txt"
But here the data1,data2,data3 .... and so on have to be accessed by me and create a textfile in each so what is the code?
Counter variable "ctr" is already evaluated in my program.
You could snprintf to create a custom string. An example is this:
char filepath[100];
snprintf(filepath, 100, "c:\\user\\Desktop\\data%d\\example.txt", datanum);
Then whatever you want to do with it:
ofstream f;
f.open(filepath);
f.close();
Note: snprintf limits the maximum number of characters that can be written on your buffer (filepath). This is very useful for when the arguments of *printf are strings (that is, using %s) to avoid buffer overflow. In the case of this example, where the argument is a number (%d), it is already known that it cannot have more than 10 characters and so the resulting string's length already has an upper bound and just making the filepath buffer big enough is sufficient. That is, in this special case, sprintf could be used instead of snprintf.
You can use the standard string streams, such as:
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
void f ( int data1 )
{
ostringstream path;
path << "c:\\user\\Desktop\\" << data1 << "\\example.txt";
ofstream file(path.str().c_str());
if (!file.is_open()) {
// handle error.
}
// write contents...
}

Storing NUL characters (ASCII 0)

I've created a program in C++ that prompts the user for a filename and for the requested filesize. The program checks if the requested filesize is bigger than the actual filesize and then adds null characters (the ones with code 0) at the end of the file, until the requested filesize is reached.
I have done it like this (with fstream):
for (blah blah) {
file << '\0'; // ('file' is an fstream object)
}
and it worked just as I wanted it to. I know this is a bad code as it may torture the hard disk by sending many calls to it (and it's slow by the way). This was only for testing reasons. Then, because of this problem I decided to create a variable storing the NUL characters and save the whole variable to the file at once (without saving each character separately).
Then the problem appeared... because of the NUL character (also known as null-terminator), terminating the string, I couldn't store those zeros in any way.
I've tried an array of chars, a string and even a stringstream, but none worked (there's something interesting about stringstream, when I used it, the file's content looked like this: 0x47c274). Anyway, it didn't work as I expected it to.
Is there any efficient way of storing an array of null characters?
Store them in an array of characters and use ostream::write to write the array to the file.
Here's an example:
#include <algorithm>
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ofstream fout("pokemon");
char buffer[1000];
std::fill(buffer, buffer + 1000, '\0');
fout.write(buffer, sizeof(char) * 1000);
return 0;
}