fgets - maximum size (int num) - c++

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.

Related

The best method for filling char array (gets vs cin.getline)

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.

How to read number of characters stored in input stream buffer

I have a quick question - how can I possibly write something in console window to std::cin without assigning it to a string or char[]? And then how to read the number of characters that are stored in buffer?
Let's say that I want to create an array of char, but it shall has the size of the input length. I might create a buffer or a variable of big size to store the input and then read its length, allocate memory to my char array and copy it. But let's also say that I am a purist and I don't want any additional (other than stream buffer) memory used. Is there a possibility to access std::cin buffer, read the number of characters stored and copy them to my array? I was trying to find the answer for several hours, reading cpp reference but I really couldn't find solution. I couldn't even find if there is a possibility to write something to std::cin buffer without assigning it to a variable, aka executing cin >> variable. I would appreciate any help, also if you have alternative solutions for this problem.
Also, does somebody know where can I find information about how buffers work (means where computer stores input from keyboard, how it is processed and how iostream works with computer to extract data from this).
Many thanks!
First of all in order for the input buffer to be filled you need to do some sort of read operation. The read operation may not necessary put what is read in to a variable. For example, cin.peek() may block until the user enters some value and returns the next character that will be read from the buffer without extracting it or you could also use cin.get along with cin.putback.
You can then use the streambuf::in_avail function to determine how many characters are in the input buffer including a new line character.
With that in mind you could do something like this:
char ch;
cin.get(ch);//this will block until some data is entered
cin.putback(ch);//put back the character read in the previous operation
streamsize size=cin.rdbuf()->in_avail();//get the number of character in the buffer available for reading(including spaces and new line)
if(size>0)
{
char* arr=new char[size];//allocate the size of the array(you might want to add one more space for null terminator character)
for(streamsize i=0;i<size;i++)
cin.get(arr[i]);//copy each character, including spaces and newline, from the input buffer to the array
for(streamsize i=0;i<size;i++)
cout<<arr[i];//display the result
}
That being said, i am sure you have a specific reason for doing this, but i don't think it is a good idea to do I/O like this. If you don't want to estimate the size of the character array you need for input then you can always use a std::string and read the input instead.

Using ifstream's getLIne C++

Hello World,
I am fairly new to C++ and I am trying to read a text file Line by Line. I did some research online and stumbled across ifstream.
What is troubling me is the getLine Method.
The parameters are istream& getline (char* s, streamsize n );
I understand that the variable s is where the line being read is saved. (Correct me if I am wrong)
What I do not understand is what the streamsize n is used for.
The documentation states that:
Maximum number of characters to write to s (including the terminating null character).
However if I do not know how long a given line is what do I set the streamsize n to be ?
Also,
What is the difference between ifstream and istream ?
Would istream be more suitable to read lines ? Is there a difference in performance ?
Thanks for your time
You almost never want to use this getline function. It's a leftover from back before std::string had been defined. It's for reading into a fixed-size buffer, so you'd do something like this:
static const int N = 1024;
char mybuffer[N];
myfile.getline(mybuffer, N);
...and the N was there to prevent getline from writing into memory past the end of the space you'd allocated.
For new code you usually want to use an std::string, and let it expand to accommodate the data being read into it:
std::string input;
std::getline(myfile, input);
In this case, you don't need to specify the maximum size, because the string can/will expand as needed for the size of the line in the input. Warning: in a few cases, this can be a problem--if (for example) you're reading data being fed into a web site, it could be a way for an attacker to stage a DoS attack by feeding an immense string, and bringing your system to its knees trying to allocate excessive memory.
Between istream and ifstream: an istream is mostly a base class that defines an interface that can be used to work with various derived classes (including ifstream objects). When/if you want to open a file from disk (or something similar) you want to use an ifstream object.

parse an unknown size string

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.

How to use fgets if you don't know the number of characters to be read?

I need to read a file and send the text from it to a string so I can parse it. However, the program won't know exactly how long the file is, so what would I do if I wanted to use fgets(), or is there a better alternative?
Note:
char *fgets(char *str, size_t num, FILE *stream);
Don't forget that fgets() reads a line at a time, subject to having enough space.
Humans seldom write lines longer than ... 80, 256, pick a number ... characters. POSIX suggests a line length of 4096. So, I usually use:
char buffer[4096];
while (fgets(buffer, sizeof(buffer), fp))
{
...process line...
}
If you are worried that someone might provide more than 4K of data in a single line (and a machine generated file, such as HTML or JSON, might contain that), then you have to decide what to do next. You can do any of the following (and there are likely some other options I've not mentioned):
Process the over-long lines in bits without assuming that there was a newline in between.
Allocate memory for a longer line (say 8K to start with), copy the initial 4K into the allocated buffer, and read more data into the second half of the buffer, iterating until you find the end of line.
Use the POSIX 2008 function getline() which is available on Linux. It does memory allocation for you.
You can use fgets iteratively, but a simpler alternative is (stdio.h's) getline. It's in POSIX, but it's not standard C.
Since you're using C++ though, can you use std::string functions like iostream's getline?
If you're not on a POSIX system and don't have getline available, take a look at Chuck Falconer's public domain ggets/fggets functions which dynamically grow a buffer to consume an entire line. (That link seems to be down right now, but archive.org has a copy.)
Allocate a buffer (the one that str points to), and pass the size of the buffer for num. The actual space taken up will only be the length of the text read by fgets.
Something like:
char str[1000];
fgets(str, 1000, &file);
If the next line only has 10 characters before the newline, then str will hold those 10 characters, the newline, and the null terminator.
Edit: just in case there is any confusion, I didn't intend the above to sound as if the extra space in the buffer isn't in use. I only meant to illustrate that you don't need to know ahead of time how long your string is going to be, as long as you can put a maximum length on it.