Okay so my question is simple..
We all know that how bad the gets is in C & hence the advice is to use fgets.
Now in C++ we use std::string s and std::getline(std::cin, s)..Now my question is that does getline() has the same boundary checking issue like gets()..
If yes then for char input[100] & cin.getline(input,sizeof(input)); will work for char array but while using string can I write this?
std::string s; & cin.getline(s, s.capacity()); ...is this appropriate or something else can I write??
No, getline does not have the same issues as gets. The function has a reference to the string, and so can call the string's size and capacity member functions for boundary checking purposes. However, it doesn't need to do that, because it also has access the string's resizing member functions, such as push_back, resize or operator+=, which will handle boundary checking automatically, reallocating when necessary.
get() leaves the delimiter in the queue thus letting you able to consider it as part of the next input. getline() discards it, so the next input will be just after it.
If you are talking about the newline character from a console input,it makes perfectly sense to discard it, but if we consider an input from a file, you can use as "delimiter" the beginning of the next field.
Related
I'm using C ++ 11. I'm wondering if there are any advantages to using cin.getline () compared to gets ().
I need to fill a char array.
Also, should I use fgets or getline for files?
I'm wondering if there are any advantages to using cin.getline () compared to gets ().
I am assuming you really mean gets, not fgets.
Yes, there definitely is. gets is known to be a security problem. cin.getline() does not suffer from that problem.
It's worth comparing fgets and cin.getline.
The only difference that I see is that fgets will include the newline character in the output while cin.getline won't.
Most of the time, the newline character is ignored by application code. Hence, it is better to use cin.getline() or istream::getline() in general. If presence of the newline character in the output is important to you for some reason, you should use fgets.
Another reason to prefer istream::getline is that you can specify a character for the delimiter. If you need to parse a comma separated values (CSV) file, you can use:
std::ifstream fstr("some file name.csv");
fstr.getline(data, data_size, ',');
Of course.
First of all gets doesn't check of length of the input - so if the input if longer than char array, you are getting an overflow.
On the other hand cin.getline allows to specify the size of stream.
Anyway, the consensus among C++ programmers is that you should avoid raw arrays anyway.
I know that when writing code like std::cin >> some_var; , where some_var is a string variable, only the first word that was inputted will be stored in some_var. But I do not understand why std::cout << "something here"; does not only output "something". Am I missing something?
When reading input using cin >> some_var, the delimiter is space by default (you can change this though), while when printing, cout prints till its find \0 which is end of the string.
If you want to read till it finds \0 in the input stream, then you've to write this:
std::getline(std::cin, some_var, '\0');
You can give any other character as delimiter as third argument of std::getline function.
Note that there is a member function with same name getline which is slightly different than the one I used above which is a free standalone function.
Compare:
std::getline - free standalone function. An overloaded function is also available.
istream::getline - member function of std::istream
I used the first one.
It was deemed useful that cin, when reading into a string terminates at whitespace. But it wasn't deemed useful that only the first word is printed when you print a string.
After all you said print "something here" to cout· In the other case, you just said read something from cin. The choice between a word, between a line and between the whole content of stdin (until an EOF is received) is arbitrary and the design happens to be to read a word. That makes it easy to quickly read a record line like "john 10 2.15" (first read into string, then into an int, and then into a float). Use std::getline to read a whole line into a string.
Because when you take input from std::cin, it needs to know when to stop taking input. If it didn't stop at the first word, when would it stop? However, when you output a variable, the answer is easy- you output that one variable.
Yes... cin stops at a space because, by default, it thinks you want a word. cout doesn't follow the same restriction, because, well, why would it? Think about it for a second — would it make any sense whatsoever if printing out "Hello, world!" actually just printed out "Hello,"? Of course it doesn't make any sense. The developer knows what they want to output (at least, we hope :D).
I think they took a convention and stick to it. In the case of <<, it is clear that you specify what to be written. In the case of a >>, they have to decide where to stop. Newline? Maybe this is the most natural alternative, but they just decided to stop reading at a space.
The delimiters are different for cin and for cout. For cin, input is split at whitespaces, for cout, at end of lines. You can change those default delimiters though.
I am trying to read an unknown size string from a text file and I used this code :
ifstream inp_file;
char line[1000] ;
inp_file.getline(line, 1000);
but I don't like it because it has a limit (even I know it's very hard to exceed this limit)but I want to implement a better code which reallocates according to the size of the coming string .
The following are some of the available options:
istream& getline ( istream& is, string& str, char delim );
istream& getline ( istream& is, string& str );
One of the usual idioms for reading unknown-size inputs is to read a chunk of known size inside a loop, check for the presence of more input (i.e. verify that you are not at the end of the line/file/region of interest), and extend the size of your buffer. While the getline primitives may be appropriate for you, this is a very general pattern for many tasks in languages where allocation of storage is left up to the programmer.
Maybe you could look at using re2c which is a flexible scanner for parsing the input stream? In that way you can pull in any sized input line without having to know in advance... for example using a regex notation
^.+$
once captured by re2c you can then determine how much memory to allocate...
Have a look on memory-mapped files in boost::iostreams.
Maybe it's too late to answer now, but just for documentation purposes, another way to read an unknown sized line would be to use a wrapper function. In this function, you use fgets() using a local buffer.
Set last character in the buffer to '\0'
Call fgets()
Check the last character and see if it's still '\0'
If it's not '\0' and it's not '\n', implies not finished reading a line yet. Allocate a new buffer and copy the data into this new buffer and go back to step (1) above.
If there is already an allocated buffer, call realloc() to make it bigger. Otherwise, you are done. Return the data in an allocated buffer.
This was a tip given in my algorithms lecture.
can anyone tell me why gets(abc) works with char[] but not with int?
int abc;
char name[] = "lolrofl";
printf("Hello %s.\n",name);
printf("\n >> ");
fflush(stdin);
gets (abc);
printf("\n die zahl ist %i.\n",abc);
system("Pause");
return(0);
The prototype for gets() is:
char* gets(char *s);
Note that the function DOES NOT read just a single character and place it in s; it actually reads an entire string into s. However, since gets() does not provide a way of specifying the maximum number of characters to read, this can actually read more characters into s than there are bytes allocated for s. Thus, this function is a serious buffer overflow vulnerability, and you should not use this function, ever. There are alternative, safer functions which allow you to read input from the user such as fgets() and getc().
If you are using C++, then using the C++ I/O Stream Library (std::cin, std::cout, std::ostream, std::istream, std::fstream, etc.) is a far better way to perform input/output than using these other functions.
The function gets() is so dangerous, in fact, that in my development and coding custom search engine, I have taken out a promotion on gets and several other such functions warning not to use it!
Because it only reads characters. Use scanf() for formatted reading.
By the way, since you appear to be using C++ (or at least your choice of tags says so), perhaps you should try std::cin/std::cout.
If you take a look at the C Reference your question will be answered. I'll paste it for you:
char *gets( char *str );
The gets() function reads characters
from stdin and loads them into str,
until a newline or EOF is reached. The
newline character is translated into a
null termination. The return value of
gets() is the read-in string, or NULL
if there is an error. Note that gets()
does not perform bounds checking, and
thus risks overrunning str. For a
similar (and safer) function that
includes bounds checking, see fgets().
So you won't be able to cast a whole string to an integer.
First, the gets function is for reading strings or text, not numbers.
Second, don't use gets as it has buffer overrun errors. See C Language FAQ for more information. The function fgets is a safer alternative.
Third, you may want to switch to C++ streams and std::string. The C++ streams are more type friendly than C streams.
Fourth, fflush does not function on input streams. The fflush function is for writing the remaining data in stream buffers to the output stream. In C++, there is a method, ignore, which will ignore incoming characters until a newline (default) or a specified character is read (or a limit is reached).
Hope that helps.
I'm on a custom C++ crash course. I've known the basics for many years, but I'm currently trying to refresh my memory and learn more. To that end, as my second task (after writing a stack class based on linked lists), I'm writing my own string class.
It's gone pretty smoothly until now; I want to overload operator>> that I can do stuff like cin >> my_string;.
The problem is that I don't know how to read the istream properly (or perhaps the problem is that I don't know streams...). I tried a while (!stream.eof()) loop that .read()s 128 bytes at a time, but as one might expect, it stops only on EOF. I want it to read to a newline, like you get with cin >> to a std::string.
My string class has an alloc(size_t new_size) function that (re)allocates memory, and an append(const char *) function that does that part, but I obviously need to know the amount of memory to allocate before I can write to the buffer.
Any advice on how to implement this? I tried getting the istream length with seekg() and tellg(), to no avail (it returns -1), and as I said looping until EOF (doesn't stop reading at a newline) reading one chunk at a time.
To read characters from the stream until the end of line use a loop.
char c;
while(istr.get(c) && c != '\n')
{
// Apped 'c' to the end of your string.
}
// If you want to put the '\n' back onto the stream
// use istr.unget(c) here
// But I think its safe to say that dropping the '\n' is fine.
If you run out of room reallocate your buffer with a bigger size.
Copy the data across and continue. No need to be fancy for a learning project.
you can use cin::getline( buffer*, buffer_size);
then you will need to check for bad, eof and fail flags:
std::cin.bad(), std::cin.eof(), std::cin.fail()
unless bad or eof were set, fail flag being set usually indicates buffer overflow, so you should reallocate your buffer and continue reading into the new buffer after calling std::cin.clear()
A side note: In the STL the operator>> of an istream is overloaded to provide this kind of functionality or (as for *char ) are global functions. Maybe it would be more wise to provide a custom overload instead of overloading the operator in your class.
Check Jerry Coffin's answer to this question.
The first method he used is very simple (just a helper class) and allow you to write your input in a std::vector<std::string> where each element of the vector represents a line of the original input.
That really makes things easy when it comes to processing afterwards!