Hi,
Basically, I'm trying to make a program that reads a pre-created text
file. The thing is, I can get the text out of my text file, and put it
into a char variable, but what I want to do is somehow get the numbers
(there are a bunch of numbers in the text file) from the text file,
and turn them into int variables. I was figuring on doing it with
std::atoi, that's worked for me before, in other programs, but when I
try to convert my char variable (that I got with ifile.get) the thing
gives me an error message. I was wondering if any of you guys could
help me out, maybe change my program a little, so that I can get y to
be the integer it would be in the text file. By the way, teams.dat is
just a text file that should include a few random numbers.
#include <iostream>
#include <fstream>
#include <cstdlib>
int main()
{
std::cout << "Opening output file..." << std::endl;
std::ifstream ifile("c:/teams.dat", std::ios::binary);
char x;
int y;
ifile.get(x);
y = std::atoi(x)
std::cout << x << y;
return 0;
}
Thanks, any help would be totally appreciated.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
john2003_smith2003
|
11/2/2004 9:39:42 PM |
|
John Smith wrote:
> Basically, I'm trying to make a program that reads a pre-created text
> file. The thing is, I can get the text out of my text file, and put it
> into a char variable
A text is a sequence of letters, a 'char' variable can only hold a single
letter though...
> , but what I want to do is somehow get the numbers
> (there are a bunch of numbers in the text file) from the text file,
> and turn them into int variables. I was figuring on doing it with
> std::atoi, that's worked for me before, in other programs, but when I
> try to convert my char variable (that I got with ifile.get) the thing
> gives me an error message. I was wondering if any of you guys could
> help me out, maybe change my program a little, so that I can get y to
> be the integer it would be in the text file. By the way, teams.dat is
> just a text file that should include a few random numbers.
[...]
> std::cout << "Opening output file..." << std::endl;
> std::ifstream ifile("c:/teams.dat", std::ios::binary);
Two things here:
1. The first line says that you are opening an output file, but on the
second line you open the file for input.
2. I highly doubt that you know what you are doing with the
'std::ios::binary' (which should rather be std::ios_base::binary, btw).
> char x;
> ifile.get(x);
You try to read a single letter from the file here(and you didn't check if
that succeeded).
> int y;
> y = std::atoi(x)
(Note: how about 'int y = std::atoi(x)' ?)
atoi() converts a C-style string to the number it represents. A C-style
string in an array of 'char', delimited by a NUL. You however only have a
single char.
You can either put it into such an array, or use the fact that the numbers
from 0 to 9 are contiguous and simply use
int y = x-'0';
This of course will yield unwanted results if x is not in the range of '0'
to '9'.
Else, if you want to read numbers, as opposed to mere digits, you could use
the normal stream functions:
int y;
if(ifile >> y)
std::cout << "read an integer: " << y << std::endl;
Uli
--
FAQ: http://parashift.com/c++-faq-lite/
/* bittersweet C++ */
default: break;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Ulrich
|
11/3/2004 10:00:39 AM
|
|
john2003_smith2003@hotmail.com (John Smith) wrote
> Basically, I'm trying to make a program that reads a pre-created text
> file. The thing is, I can get the text out of my text file, and put it
> into a char variable, but what I want to do is somehow get the numbers
> (there are a bunch of numbers in the text file) from the text file,
> and turn them into int variables. I was figuring on doing it with
> std::atoi, that's worked for me before, in other programs, but when I
> try to convert my char variable (that I got with ifile.get) the thing
> gives me an error message. I was wondering if any of you guys could
> help me out, maybe change my program a little, so that I can get y to
> be the integer it would be in the text file. By the way, teams.dat is
> just a text file that should include a few random numbers.
To use atoi, you need to pass the address of a null-terminated string.
char buff[2];
ifile.get(buff[0]);
buff[1] = '\0';
y = std::atoi(buff);
But this only works for integers that are 1 character long (0 to 9).
Why not just stream in the integer?
ifile >> y;
I'm probably missing some nuance of your question.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
allan_w
|
11/5/2004 3:00:30 AM
|
|
Ulrich Eckhardt <doomster@knuut.de> wrote in message
news:<2urf6iF2ail1lU1@uni-berlin.de>...
> 2. I highly doubt that you know what you are doing with the
> 'std::ios::binary' (which should rather be std::ios_base::binary, btw).
Why?
Why should I have to remember which flags/functions are part of
ios_base, and which are part of basic_ios<>? IMHO, it's a lot simpler
just to use ios, and be done with it.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
kanze
|
11/5/2004 3:13:45 AM
|
|
Thanks for all your responses guys, they have been very helpful! I see
what you mean about std::atoi only being useful for reading single
digits, and hence, not that useful.
I'm trying to use the stream thing to get the info out of the text
file now. I have a bit of a problem though. Basically, I want to be
able to read in a string that includes some white space, but I don't
see how I can do it. Following is the code that illustrates the
problem.
BTW The text file is just a file called "teams2.dat" that includes the
text "Brutal Deluxe , 1 1 2 3".
#include <iostream>
#include <string>
#include <fstream>
int main()
{
std::ifstream is("c:/teams2.dat");
std::string s;
std::string s2; // There is s2 here because ultimately I'd like
int a; // to be able to extract strings from files
while (is >> s) // that include spaces in the middle
{ // e.g. "Brutal Deluxe" would be a string.
if (s == ",") // It would probably be better if I could
break; // include the space in the s string somehow.
s2 = s2 + s;
}
std::cout << "s2 = " << s2 << "\n";
while (is >> a)
{
std::cout << "a = " << a << "\n";
}
if( is.eof() )
{
std::cerr << "An I/O error occurred.\n";
}
return 0;
}
I suppose ideally it would end up with s being "Brutal Deluxe". I
think my problem is all to do with the way stream uses white space to
separate the stuff it reads in. Would there be any way to change it so
that it only changes variable each time it finds a comma, so it just
copies all the white space it finds into the string variable?
Anyway, again, thanks for your help, dudes, it's seriously useful.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
john2003_smith2003
|
11/8/2004 11:41:44 PM
|
|
In article <839d4968.0411080452.11687310@posting.google.com>, John
Smith <john2003_smith2003@hotmail.com> wrote:
> Thanks for all your responses guys, they have been very helpful! I see
> what you mean about std::atoi only being useful for reading single
> digits, and hence, not that useful.
>
> I'm trying to use the stream thing to get the info out of the text
> file now. I have a bit of a problem though. Basically, I want to be
> able to read in a string that includes some white space, but I don't
> see how I can do it. Following is the code that illustrates the
> problem.
>
> BTW The text file is just a file called "teams2.dat" that includes the
> text "Brutal Deluxe , 1 1 2 3".
>
> #include <iostream>
> #include <string>
> #include <fstream>
>
> int main()
> {
> std::ifstream is("c:/teams2.dat");
> std::string s;
> std::string s2; // There is s2 here because ultimately I'd
> like
> int a; // to be able to extract strings from files
> while (is >> s) // that include spaces in the middle
> { // e.g. "Brutal Deluxe" would be a string.
> if (s == ",") // It would probably be better if I could
> break; // include the space in the s string somehow.
> s2 = s2 + s;
> }
> std::cout << "s2 = " << s2 << "\n";
> while (is >> a)
> {
> std::cout << "a = " << a << "\n";
> }
> if( is.eof() )
> {
> std::cerr << "An I/O error occurred.\n";
> }
> return 0;
> }
>
If you have one such string and a file containing an arbitrary
number of ints folllowing the ',' then
std::istream & read_data(std::istream &in,std::string
&name,std::vector<int> &vals)
{
if(getline(in,name,','))
` {
std::copy(std::istream_iterator<int>(in),
std::istream_iterator<int>(), std::back_inserter(vals));
}
return in;
}
This reads the chars upto and excluding the ',' into name
,discarding the ',' and then reads the rest of the file of ints into a
vector<int>.
int main()
{
std::ifstream("c::/teams2.dat");
std::string name;
std::vector<int> vals;
if(read_data(in,name,vals))
{
std::cout << name << ":\n";
std::copy(vals.begin(),
vals.end(),std::ostream_iterator<int>(std::cout,\n")';
}
else
std::cout << "File input error\n";
}
if you have 'lines of data" like the above read each line with
std::getline() and place in an istringstream and parse that stream with
read_data.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Carl
|
11/9/2004 12:25:35 PM
|
|
john2003_smith2003@hotmail.com (John Smith) wrote in message
news:<839d4968.0411080452.11687310@posting.google.com>...
> I'm trying to use the stream thing to get the info out of the text
> file now. I have a bit of a problem though. Basically, I want to be
> able to read in a string that includes some white space, but I don't
> see how I can do it. Following is the code that illustrates the
> problem.
> BTW The text file is just a file called "teams2.dat" that includes the
> text "Brutal Deluxe , 1 1 2 3".
> #include <iostream>
> #include <string>
> #include <fstream>
> int main()
> {
> std::ifstream is("c:/teams2.dat");
> std::string s;
> std::string s2; // There is s2 here because ultimately I'd like
> int a; // to be able to extract strings from files
> while (is >> s) // that include spaces in the middle
> { // e.g. "Brutal Deluxe" would be a string.
> if (s == ",") // It would probably be better if I could
> break; // include the space in the s string somehow.
> s2 = s2 + s;
> }
> std::cout << "s2 = " << s2 << "\n";
> while (is >> a)
> {
> std::cout << "a = " << a << "\n";
> }
> if( is.eof() )
> {
> std::cerr << "An I/O error occurred.\n";
> }
> return 0;
> }
> I suppose ideally it would end up with s being "Brutal Deluxe".
The question is how you determine where the string should end. The
standard offers two simple solutions: the next white space, or the end
of line (using getline). Anything else is up to you, and the "best"
solution depends a lot on context. I use different solutions, according
to context.
If the input is line oriented, I will usually read it line by line using
getline, and then parse each line. If the lines are separated into
fields, I have a class FieldArray which separates the line into fields;
what determines a field is determined by the derived class, and it
wouldn't be too difficult to create a class where the first field is up
to the first comma, and the rest of the fields are separated by white
space. (This class is available at my site, www.gabi-soft.fr.)
If the format of a line is fixed, with always the same number of fields,
using something like boost::regex is even more powerful -- if you always
have exactly four numbers, for example, a regular expression along the
lines of:
*[[:space:]]*\\([^,]*[^,[:space:]]\\)[[:space:]]*,[[:space:]]*"
"\\([[:digit:]]+\\)[[:space:]]+"
"\\([[:digit:]]+\\)[[:space:]]+"
"\\([[:digit:]]+\\)[[:space:]]+"
"\\([[:digit:]]+\\)[[:space:]]*"
Will allow you to pick out the five fields as partial matches. (If you
will ever have to do any input parsing, then you should definitly become
familiar with regular expressions.)
In both cases, you would then use istringstream on each numeric field to
convert it.
> I think my problem is all to do with the way stream uses white space
> to separate the stuff it reads in. Would there be any way to change it
> so that it only changes variable each time it finds a comma, so it
> just copies all the white space it finds into the string variable?
In theory, you could define a ctype facet which recognized comma (and
only comma) as white space, and imbue that. In practice, however, that
would be a lot of work; it would also be real abuse of the intent of
imbued locales, and thus probably completely inintelligible for the
personne who follows you. And a simple function, getUntilComma, should
be trivial to write. (One of the concrete instances of my FieldArray
separates fields according to a given character. Note, however, that it
only works on string, so you have to read the line first, and that the
instances present at my site all use the same criteria for separating
all of the fields -- although as I said, it would be simple enough to
create one that worked differently.)
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
kanze
|
11/9/2004 9:08:29 PM
|
|
Carl Barron <cbarron413@adelphia.net> wrote in message
news:<081120041953139312%cbarron413@adelphia.net>...
> In article <839d4968.0411080452.11687310@posting.google.com>, John
> Smith <john2003_smith2003@hotmail.com> wrote:
> > Thanks for all your responses guys, they have been very helpful! I
> > see what you mean about std::atoi only being useful for reading
> > single digits, and hence, not that useful.
> > I'm trying to use the stream thing to get the info out of the text
> > file now. I have a bit of a problem though. Basically, I want to be
> > able to read in a string that includes some white space, but I
> > don't see how I can do it. Following is the code that illustrates
> > the problem.
> > BTW The text file is just a file called "teams2.dat" that includes
> > the text "Brutal Deluxe , 1 1 2 3".
> If you have one such string and a file containing an arbitrary
> number of ints folllowing the ',' then
> std::istream & read_data(std::istream &in,std::string
> &name,std::vector<int> &vals)
> {
> if(getline(in,name,','))
> ` {
> std::copy(std::istream_iterator<int>(in),
> std::istream_iterator<int>(), std::back_inserter(vals));
> }
> return in;
> }
> This reads the chars upto and excluding the ',' into name
> ,discarding the ',' and then reads the rest of the file of ints into a
> vector<int>.
More likely, he has given an example of a typical line in the file.
Without having an exact specification of the input file (e.g. what is
allowed, what isn't, etc.), it's difficult to say more. However:
- Using getline for this sort of thing is not very robust. If we are
speaking about a line format, then if the comma is missing (due to a
typing error, for example), getline will not report an error, but
will simply gobble up too much text.
Again, we really need to know more about the format. In general,
getline is useful if and only if there is exacty one character which
should cause us to stop. This is typically only the case at the top
level; at lower levels, we want to stop when we reach the end of a
higher level as well, possibly handling the error. A lot of simple
file formats are line oriented, which means that getline can only
effectively be used for reading lines. On the file -- one common
technique is to read the line, then use it to initialize an
std::istringstream. If this is done, your getline technique would
be quite appropriate on the istringstream (which we already know
contains one, and only one, line from the source).
- Similarly, I've yet to see a realistic case where an
istream_iterator was usable on an input file (maybe some machine
generated file?). Simply because it doesn't stop, and it doesn't
allow any syntax verification. Again, it might be appropriate for
parsing an istringstream containing just one line of the original
file.
More generally, for the initial poster: before even starting to look for
a solution, define the problem exactly. Specify the exact format of the
input file, and what you expect to do in case the actual file doesn't
conform. If humans are to have anything to do with the file:
- The more error checking the better. Define some redundance in the
format, so that you can recognize common errors. If the file is
more than about 10 lines long, try to define the format so that you
can resynchronize in case of error, and continue, to possibly catch
additional errors. (For simple formats, the most common
"resynchronization" point is the end of a line. If you read the
file line by line using getline, and then parse each individual
line, your code will handle this automatically.)
- A minimum error message will include the filename and the
line number.
- If humans are to have anything to do with the file, ever, then
provide some sort of commenting mechanism -- the simplest for line
oriented files is to choose some character which cannot otherwise
occur in the file, and treat it and everything following it on the
line as a comment. This can easily be done by means of a filtering
streambuf (see my site, www.gabi-soft.fr), or if you are reading
line by line, a trivial regular expression on the line you just
read, e.g.: "[^#]*", then using only the matched part as the "line".
And don't forget to allow additional white space just about
everywhere (leading, between fields, etc.), and empty lines.
--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orient�e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S�mard, 78210 St.-Cyr-l'�cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
kanze
|
11/11/2004 11:16:38 AM
|
|
|
7 Replies
228 Views
(page loaded in 0.134 seconds)
Similiar Articles: std.textio.all procedure read - comp.lang.vhdl... I am trying to create a macro to read all the files and ... processing instead of (macro-) looping over some procedure. ... Reading text files, std::atoi, Char Variables ... Read file twice and modify content - comp.lang.awkHow to read a text (txt) file, modify and save - comp.soft-sys ... Read file twice and modify content - comp.lang.awk open file, change content, save file ... of java code ... Converting number to std::string ("itoa()" ) - comp.lang.c++ ...... to construct a std::string > > from a numerical variable ... is: int atoi(char const ... PDF files considered Unsafe by MS - comp.text.pdf Converting number to std::string ... integer overflow in atoi - comp.lang.cSo I did this : int atoi(char str ... integer overflow in atoi - comp.lang.c File read ... lang.c integer overflow in atoi - comp.lang.c Incrementing an enum variable ... from std::string to std::istream? - comp.lang.c++-- -Gernot int main(int argc, char** argv) {printf ... Read(istram& is) { } because I don't have a file to read ... I store following text in std::string. std::string a ... How to implement a function to copy file on LINUX ? - comp.unix ...... it can be done as: void copy_file(const char *src ... include <iostream> using namespace std ... How to implement batch print pdf file programmatically - comp.text ... problem with mixed c and fortran code - comp.lang.fortran ...... compiler, you have to either read ... char1.f90 C:\gfortran\clf\char_c>type char1.s .file "char1.f90" .text ... gfortran\clf\char_std>type char_std.f90 ... Extracting a ROI from an image. - comp.soft-sys.matlabclear; % Delete all variables. close all; % Close all ... so-called mmROI), which returns ROI mean, std, min ... ROI coordinates were automatically saved into a text file ... Braces within a string - comp.lang.awk... string - comp.lang.awk A file name is a user-visible text string ... to find a way to substitute a variable ... std.textio.all procedure read - comp.lang.vhdl Braces within a ... Sockets in gfortran? - comp.lang.fortran... that can't be read */ #define FTW_NS 4 /* file that we can't stat */ static char ... Input text to send ... warning: unused variable pid $ gcc -c -D_GNU_SOURCE -std ... read numbers from a text file and save them as integerSo i want to read the text file and save the string "1234" into int number variable. the int ... using namespace std; ifstream s ... FileName[1024]) { char ... Help - load numbers from a .txt file to variables (c++) - Stack ...I want to read the text file, line to line, and save one line to one variable like: Line1 ... 0; z=0; char ... the vector and convert std::string using atoi. ... 7/25/2012 3:50:13 PM
|