C++ fstream getline parameters - c++

I am new to C++ and I want to ask a question about how to find a line in a file using fstream.
I only found this and would someone explain to me what these parameters mean?
file.getline(char *,int sz);
Thanks

If you mean std::basic_stream::getline(), you provide a pointer to character array and the size of that array. You have to create the array somewhere by yourself. If some line is longer than sz - 1, only part of it with length sz - 1 will be read.
If you don't know the maximum length of lines in the input file, it's better to use std::getline(), for example like this:
std::string line;
std::getline(file, line);

Directly from here:
The first variable:
Pointer to an array of characters where extracted characters are stored as a c-string.
The second variable:
Maximum number of characters to write to s (including the terminating null character).
If the function stops reading because this limit is reached without finding the delimiting character, the failbit internal flag is set.
streamsize is a signed integral type.

Related

why there are two member functions?

I am learning c++, however, I can not understand what is the difference BTW:
std::cin.get();
and
std::cin.getline();
although;I know how to use each of them, but can't understand why there are two?
I've read this explanation :
getlinereads the newline character then discard it; whereas .get()reads it then leaves it in the input queue ..!! why each of them does what it does ?
sorry for bad English :(
std::cin.get(), when called without parameters, reads one single character from input and returns it.
std::cin.getline(char* str, std::streamsize count) reads one line of input and copies it into the buffer str, followed by an extra null character to form a C-string. count must be the size of that buffer, i.e. the maximal number of characters (plus the null byte) it can copy into it.
To read a line without caring about the buffer size it may be better to use std::getline:
#include <string>
std::string line;
std::getline(std::cin, line);
Reads a line from cin into line.
See http://en.cppreference.com/w/cpp/io/basic_istream and http://en.cppreference.com/w/cpp/string/basic_string/getline .
"get" only retrieves a character, "getline" gets all characters to a line terminator. Thats the main difference.

ifstream::read doesnot append '\0'

ifstream::read just reads n bytes into a buffer, but doesn't append '\0' at the end of the buffer, right? Then when I use the buffer, how does it know the end of the buffer?
Should I manually append a '\0' at the end of the buffer?
The ifstream is used for reading from a file, binary or text. When dealing with a binary file with read, one cannot be sure the origin of a zero byte (from the file itself or appended by read) so read does not append a zero to destination buffer.
If you are working on a text file, then you can use std::getline, and receive a std::string:
istream& getline ( istream& is, string& str );
If you are reading into a std::string say, with std::getline, then string carries a length - std::string is not terminated by '\0' as C-style char* strings are. If you read into std::string and then use string.c_str() then that is null terminated. You can use this for a C-style string.
If you are reading into char* you must supply a length - that is how many bytes are read independent of any '\0' are found. In this case you should manually append a '\0' at the end of the buffer.
Yes, you are correct, you need to manually append it to the end of the buffer: buffer[length] = '\0'; if you want a null terminator.
When you call write you can also specify the length of the output: std::cout.write(buffer, length); which will output only length number of data to tell it when to stop requiring you not to use the null terminator.
I would look into std::getline and std::string for a more robust approach though.
You can put whatever you want at the end of the buffer, as long as there is space for it.
istream::read doesn't tell you how many bytes it read; it either reads everything you asked for, or changes the state of the stream to fail/eof.
If you want to handle the case where you might have less bytes than expected, use istream::readsome, it returns the number of bytes extracted.
As other answers mentioned, if you are dealing with strings, use functions that read strings, like std::getline, or the >> extractors. istream::read is for binary data - in which case std::streambuf is usually more convenient to use.
You can call ifstream::gcount() to determine the number of characters read in the read() operation.

using cin.get() function

char arr[100];
cin.get(arr,100);
Is this safe? Will the null-character be appended at the end even if I type more than 100 chars? or should I use cin.get(arr,99)?
When I type ENTER, is the end-of-line character part of the array or not?
The answers to both of your questions can be found here, but to reiterate:
The get method reads at most n - 1 characters. This means that the method expects the size of the buffer and not the number of characters to read. This method automatically appends a null character to the end.
The newline character is not extracted or stored in the array.
You may also want to consider using std::getline which you can use in conjunction with std::string.
1)is this safe. I mean will the null-character be appended
at the end. even if I typed more than 100 chars. or it must be cin.get(arr,99).
Taken from here.
The signature of get you are using looks like this:
basic_istream& get( char_type* s, std::streamsize count );
It will read at most count - 1 characters from the stream (in your case 99) or up until the delimiting character, which is by default \n. So if you type more than 100 characters, a call to get will read 99 of those characters and then append the null terminator \0 at the end.
2)also when I type ENTER, a newline get passed. so does this character is really a part of the array or not.
No, get read up until the delimiting character, so if you press ENTER, \n will be left in the stream as the next character to be read.
Advice:
Please use the site I linked to in order to understand how these functions work, and prefer std::string and std::getline if you are coding in C++.

fgets - maximum size (int num)

In my program, i'm calling the function fgets:
char * fgets ( char * str, int num, FILE * stream );
in a loop several times, and then deal with the new coming input (in case there is one).
in the fgets specifications, it says that:
num:
Maximum number of characters to be read (including the final
null-character). Usually, the length
of the array passed as str is used.
The problem is that i want to rean NO MORE than the specified num - and IGNORE the rest of it, if it's in the same line.
What i've found out, is that the fgets reads the next part of the line in the next call to the function.
How can i avoid this behavior?
You'll need to do it manually - consume the characters with fgets and copy the results to a result array until a newline character is found, dump the contents, and continue with fgets.
The size parameter is intended to be used to prevent reading more data than your buffer can hold. It won't work for skipping over data.
You'll have to write code to throw away the parts of the string you don't want after it's read.
fgets() is a old C function. The idea is that the language will provide minimal complexity functions that you can combine to do what you like. They don't include any extra capability on purpose. This keeps everyone from paying for things they don't use. Think LEGO.

istream get method behavior

I read istream::get and a doubt still hangs. Let's say my delimiter is actually the NULL '\0' character, what happens in this case? From what I read:
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.
The reason I would prefer "get" over "readline" is because of the capability to extract the character stream into a "streambuf".
I dont' quite get your problem.
On the msdn website, for the get function, it says:
In all cases, the delimiter is neither extracted from the stream nor returned by the function. The getline function, in contrast, extracts but does not store the delimiter.
In all cases, the delimiter is neither extracted from the stream nor returned by the function. The getline function, in contrast, extracts but does not store the delimiter.
http://msdn.microsoft.com/en-us/library/aa277360(VS.60).aspx
I don't think your going to have a problem, since the msdn site tells that the delimiter is neither extracted from the stream, nor returned vy the function.
Or maybe I'm missing a point here?
If you have something like this, then delimiter will not get stuck in the input stream:
std::string read_str(std::istream & in)
{
const int size = 1024;
char pBuffer[size];
in.getline(pBuffer, size, '\0');
return std::string(pBuffer);
}
just an example if you have '\0' as delimiter and strings are not bigger than 1024 bytes.