473,890 Members | 1,697 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Reading unformatted text from stdin

Greetings,

I need to read (unformatted text) from stdin up to EOF into a char
buffer; of course I cannot allocate my buffer until I know how much
text is available, and I do not know how much text is available until I
have read it... which seems to imply that multiple reads of the input
stream will be inevitable.

Now I can correctly find the number of characters available by:
|
| #include <iostream>
|
| std::cin.ignore (std::numeric_l imits<int>::max ());
| const int num_chars = std::cin.gcount ();
|
Then I would like to do:
|
| char* const text = new char[num_chars+1];
| std::cin.read(t ext,num_chars);
| text[num_chars]='\0';
|
but the read() won't work because, as I understand it, ignore() has (as
its name implies) `thrown away' all characters in the stream...!

I am sure this must be a stock situation, and wonder if there is an
(efficient, elegant) stock way of approaching it.
Any tips appreciated,

--
Lionel B

Jul 22 '05 #1
19 10403

"Lionel B" <go****@lionelb .com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
Greetings,

I need to read (unformatted text) from stdin up to EOF into a char
buffer; of course I cannot allocate my buffer until I know how much
text is available, and I do not know how much text is available until I
have read it... which seems to imply that multiple reads of the input
stream will be inevitable.

Now I can correctly find the number of characters available by:
|
| #include <iostream>
|
| std::cin.ignore (std::numeric_l imits<int>::max ());
| const int num_chars = std::cin.gcount ();
|
Then I would like to do:
|
| char* const text = new char[num_chars+1];
| std::cin.read(t ext,num_chars);
| text[num_chars]='\0';
|
but the read() won't work because, as I understand it, ignore() has (as
its name implies) `thrown away' all characters in the stream...!

I am sure this must be a stock situation, and wonder if there is an
(efficient, elegant) stock way of approaching it.
Any tips appreciated,


#include <algorithm>
#include <iostream>
#include <string>

int main()
{
std::cout << "Enter text: ";
std::string line;
std::getline(st d::cin, line);

if(!line.empty( ))
{
char * const text = new char[line.size() + 1];
std::copy(line. begin(), line.end(), text);
text[line.size()] = 0;
std::cout << text << '\n';
delete[] text;
}

return 0;
}

-Mike
Jul 22 '05 #2
Lionel B wrote:

Greetings,

I need to read (unformatted text) from stdin up to EOF into a char
buffer; of course I cannot allocate my buffer until I know how much
text is available, and I do not know how much text is available until I
have read it... which seems to imply that multiple reads of the input
stream will be inevitable.

Now I can correctly find the number of characters available by:
|
| #include <iostream>
|
| std::cin.ignore (std::numeric_l imits<int>::max ());
| const int num_chars = std::cin.gcount ();
|
Then I would like to do:
|
| char* const text = new char[num_chars+1];
| std::cin.read(t ext,num_chars);
| text[num_chars]='\0';
|
but the read() won't work because, as I understand it, ignore() has (as
its name implies) `thrown away' all characters in the stream...!
I don't understand.
Why did you do ignore() at the stream?
What should be the purpose of it?

I am sure this must be a stock situation, and wonder if there is an
(efficient, elegant) stock way of approaching it.
Any tips appreciated,


Well the tip is: If you want to read then it is unwise to first
throw away everything you want to read :-)

Besides:
Did you know that std::string can hold a very long text?
Did you know that there is a function getline for strings?
Did you know that you can tell getline() what it should use as
delimiter for 'lines'?

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 22 '05 #3
Lionel B wrote:
I need to read (unformatted text) from stdin up to EOF into a char
buffer;


What's wrong with this?

| std::ifstream in("some file", std::ios_base:: binary);
| std::ostringstr eam tmp;
| tmp << in.rdbuf();
| std::string const& contents = tmp.str();

.... or:

| std::ifstream in("some file",
std::ios_base:: binary);
| std::istreambuf _iterator<char> beg(in), end;
| std::string contents(beg, end);

Actually, I like the latter better but it is probably considerably
slower than the first alternative on most implementations .
--
<mailto:di***** ******@yahoo.co m> <http://www.dietmar-kuehl.de/>
<http://www.contendix.c om> - Software Development & Consulting

Jul 22 '05 #4
Mike Wahler wrote:
"Lionel B" <go****@lionelb .com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
Greetings,

I need to read (unformatted text) from stdin up to EOF into a
char buffer; of course I cannot allocate my buffer until I know
how much text is available, and I do not know how much text is
available until I have read it... which seems to imply that
multiple reads of the input stream will be inevitable.

/.../


#include <algorithm>
#include <iostream>
#include <string>

int main()
{
std::cout << "Enter text: ";
std::string line;
std::getline(st d::cin, line);


I guess that might work, but my input might contain '\n' chars (i.e.
the default eol chars), so I'd have to give getline() an eol char that
would never actually occur (I think '\0' would probably do it). Shall
try it.

Cheers,

--
Lionel B

Jul 22 '05 #5

"Lionel B" <go****@lionelb .com> wrote in message
news:11******** **************@ c13g2000cwb.goo glegroups.com.. .
Mike Wahler wrote:
"Lionel B" <go****@lionelb .com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
Greetings,

I need to read (unformatted text) from stdin up to EOF into a
char buffer; of course I cannot allocate my buffer until I know
how much text is available, and I do not know how much text is
available until I have read it... which seems to imply that
multiple reads of the input stream will be inevitable.

/.../
#include <algorithm>
#include <iostream>
#include <string>

int main()
{
std::cout << "Enter text: ";
std::string line;
std::getline(st d::cin, line);


I guess that might work, but my input might contain '\n' chars (i.e.
the default eol chars),


With the above code, not possible.
so I'd have to give getline() an eol char that
The default 'termination' character for 'std::getline() ' is '\n'
(this can be overridden by supplying a different one as the
third argument to 'std::getline() ' ).
would never actually occur (I think '\0' would probably do it).
On many systems, it's not possible to input a '\0' character.
Shall
try it.


Did you try what I wrote?

-Mike

Jul 22 '05 #6
Mike Wahler wrote:
"Lionel B" <go****@lionelb .com> wrote in message
news:11******** **************@ c13g2000cwb.goo glegroups.com.. .
Mike Wahler wrote:
"Lionel B" <go****@lionelb .com> wrote in message
news:11******** **************@ z14g2000cwz.goo glegroups.com.. .
> Greetings,
>
> /.../

#include <algorithm>
#include <iostream>
#include <string>

int main()
{
std::cout << "Enter text: ";
std::string line;
std::getline(st d::cin, line);
I guess that might work, but my input might contain
'\n' chars (i.e. the default eol chars),


With the above code, not possible.
so I'd have to give getline() an eol char that


The default 'termination' character for 'std::getline() ' is '\n'
(this can be overridden by supplying a different one as the
third argument to 'std::getline() ' ).


That's exactly what I was thinking of...
would never actually occur (I think '\0' would probably do it).


On many systems, it's not possible to input a '\0' character.


In my case input may be redirected from a file or piped from another
program, so input is not predictable (that's what I meant by
"unformatte d" in my original post). However, a '\0' could be considered
pathological.
Did you try what I wrote?


Yes. As expected, it fails if the input comprises multiple lines (only
the first line is read). However, it works ok if I replace:

std::getline(st d::cin, line);

with:

std::getline(st d::cin, line, '\0');
Cheers,

--
Lionel B

Jul 22 '05 #7
Karl Heinz Buchegger wrote:
Lionel B wrote:

Greetings,

I need to read (unformatted text) from stdin up to EOF into a char
buffer; of course I cannot allocate my buffer until I know how much
text is available, and I do not know how much text is available
until I have read it... which seems to imply that multiple reads of
the input stream will be inevitable.

Now I can correctly find the number of characters available by:
|
| #include <iostream>
|
| std::cin.ignore (std::numeric_l imits<int>::max ());
| const int num_chars = std::cin.gcount ();
|
Then I would like to do:
|
| char* const text = new char[num_chars+1];
| std::cin.read(t ext,num_chars);
| text[num_chars]='\0';
|
but the read() won't work because, as I understand it, ignore()
has (as its name implies) `thrown away' all characters in the
stream...!
I don't understand.
Why did you do ignore() at the stream?
What should be the purpose of it?


It was just a first cut attempt at calculating the number of characters
in the stream. The "advantage" is that it will, if invoked as above,
read to the end of the stream and enable gcount() to return the number
of characters correctly. Of course it has a fatal disadvantage...
Well the tip is: If you want to read then it is unwise to first
throw away everything you want to read :-)
.... of course ;-) What I really need is an ignore() that doesn't
ignore; i.e. an unformatted read call which reads to the end of the
stream but doesn't actually extract any chars. As far as I know no
such call exists; I suspect it may be possible to do something along
these lines with peek() in a loop. Might give that a try.
Besides:
Did you know that std::string can hold a very long text?
Did you know that there is a function getline for strings?
Did you know that you can tell getline() what it should use as
delimiter for 'lines'?


Yep. See Mike Wahler's suggestion and my reply.
Regards,

--
Lionel B.

Jul 22 '05 #8
Dietmar Kuehl wrote:
Lionel B wrote:
I need to read (unformatted text) from stdin up to EOF into
a char buffer;


What's wrong with this?

| std::ifstream in("some file", std::ios_base:: binary);
| std::ostringstr eam tmp;
| tmp << in.rdbuf();
| std::string const& contents = tmp.str();


Works well. I have also tried:

| const int nchars= std::in.rdbuf()->in_avail()-1;
| char* const text = new char[nchars+1];
| std::in.read(te xt,nchars);
| text[nchars]='\0';

(needs the "-1" in the 1st line; I guess in_avail() counts the EOF too)
which should be pretty efficient, although I am not quite sure whether
in_avail() will always give me what I expect (i.e. the entire input up
to EOF). Seems to work, though.

Cheers,

--
Lionel B

Jul 22 '05 #9
Lionel B wrote:
Dietmar Kuehl wrote:
Lionel B wrote:
I need to read (unformatted text) from stdin up to EOF into
a char buffer;


What's wrong with this?

| std::ifstream in("some file", std::ios_base:: binary);
| std::ostringstr eam tmp;
| tmp << in.rdbuf();
| std::string const& contents = tmp.str();


Works well. I have also tried:

| const int nchars= std::in.rdbuf()->in_avail()-1;
| char* const text = new char[nchars+1];
| std::in.read(te xt,nchars);
| text[nchars]='\0';

(needs the "-1" in the 1st line; I guess in_avail() counts the
EOF too) which should be pretty efficient, although I am not quite
sure whether in_avail() will always give me what I expect (i.e. the
entire input up to EOF). Seems to work, though.


Correction: seems to work *sometimes* :-/ If I pipe input in from
another program (my prog reads stdin; i.e. in = cin) then sometimes
in_avail() returns 0... maybe some synching/flushing issue? Or cruddy
implementation of pipes (this is Win2k)? Tricky to replicate exact
conditions under which it doesn't work.
So I'm sticking with Dietmar's first method for now.

--
Lionel B

Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
5855
by: Bernhard Kuemel | last post by:
Hi! I want to read/write commands and program input to/from /bin/bash several times before I close the stdin pipe. However, reading from cat hangs unless I first close the stdin pipe. <?php $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child
8
9540
by: Yeow | last post by:
hello, i was trying to use the fread function on SunOS and ran into some trouble. i made a simple test as follows: i'm trying to read in a binary file (generated from a fortran code) that contains the following three floating-point numbers: 1.0 2.0 3.0
6
2491
by: Charlie Zender | last post by:
Hi, I have a program which takes the output filename argument from stdin. Once the program knows the output filename, it tries to open it. If the output file exists, the program asks the user to confirm whether he really wants to overwrite the existing output file. The problem is that the second read from stdin, to obtain the user response whether to overwrite the existing output file, never waits for the user's response. It's as if a...
2
3184
by: Matt McGonigle | last post by:
Hi all, Please help me out with this. Perhaps it is a dumb question, but I can't seem to make it work. I am doing a file conversion using an unformatted binary file for input and outputting to a normal text file. I need to read in a float from the binary file, but it sets my input stream to failbit. Is there a special way I can read in floats? All I am doing is
1
5692
by: Andrea Gavana | last post by:
Hello NG, that may sound a silly question, but I didn't find anything really clear about the issue of reading unformatted big endian files with Python. What I was doing till now, was using Fortran to read those files and compile this Fortran extension using F2PY. Now that it seems that no possible combinations of Fortran/C compilers actually *work* with Python 2.4 on Windows XP, I was trying to translate the Fortran subroutine to...
111
20110
by: Tonio Cartonio | last post by:
I have to read characters from stdin and save them in a string. The problem is that I don't know how much characters will be read. Francesco -- ------------------------------------- http://www.riscossione.info/
25
5878
by: 7stud | last post by:
I can't break out of the for loop in this example: ------ import sys lst = for line in sys.stdin: lst.append(line) break
24
2077
by: arnuld | last post by:
I have a function named getword that read every single input from std. input. WHAT I WANTED: I want it read the word if it has less than or equal to 30 characters. Anything else beyond that should be discarded and it should ask the user for new input. Ctrl-D should exit from the program. WHAT I GOT: It reads anything beyond 30 characters as the next word :\ and I have to press Ctrl-D two times to exit from the program.
5
705
by: Luis Zarrabeitia | last post by:
I have a problem with this piece of code: ==== import sys for line in sys.stdin: print "You said!", line ==== Namely, it seems that the stdin buffers the input, so there is no reply until a huge amount of text has bin written. The iterator returned by xreadlines
0
9976
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9815
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11215
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10908
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10451
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9618
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
8008
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5835
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4665
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.