Is this safe std::string code?

Started by
14 comments, last by Shannon Barber 20 years, 7 months ago

std::string line;
while(!fstr.eof())
	{
	line.resize(256, ''\0'');
	fstr.getline(&*line.begin(), (std::streamsize)line.size(), ''\n'');
	}
 
I was skeptical, but it does work on the two implementations I have to try it on. Is the practicality of std::string like that of std::vector?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Advertisement
Hello Magmai,

yes std::string is perfectly legal.
all standard library class can be access by std::
one way to get around the use of using std:: is by
have a using(std) this tells the compiler to look in this namesapce for anyhting you use that appear in after or in the block the using appears. Though I would not use this in a header file.
To many using( ) is not good but a few well place ones work great.
In a source file using a lot if standard library class just put using(std) after all your includes and before your code. And you won''t have to type std:: for every cout, endl, map, vector, list, string, cerr, setw, etc.

Lord Bart
I'm sorry, I should have been more explicit.
I am curious about the direct use of the underlying buffer,
fstr.getline(&*line.begin() ,

i.e. is the memory provided by std::string iterators guaranteed to be linear, as it is with vectors (or rather, is it a universal implementation as it is with vectors).


[edited by - Magmai Kai Holmlor on September 2, 2003 7:37:30 PM]
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Here''s how I would write this:
std::ifstream fstr("file.dat"); std::string line; while(std::getline(fstr, line)){    // do stuff with line...} 


I don''t know if what you wrote is guaranteed to be legal or not. Accessing the raw pointer to the internal storage via an iterator seems a bit fishy. I''d be tempted to avoid it wherever possible, and in this case I would think it is possible.
Bart: Errrrr... I think MKH knows plenty about namespaces.

Magmai: It isn''t technically legal; basic_strings are not currently required to have packed-array representation. However, all the implementations I know of do. (it''s the same deal with vectors) Many people consider this lack of specification to be a mistake, and IIRC, it''ll be remedied in the next STL spec. For the time being, tho, don''t worry about it. HOWEVER, remember that after your getline, line is a 256-character string which probably has an embedded null in it and garbage after that. Treat it as such.

How appropriate. You fight like a cow.
Ahhh, almost would have to resize again to the size of the string read, eh?

Thanks GrinningGator, I was also curious how you're suppose to do this

[edited by - Magmai Kai Holmlor on September 2, 2003 7:45:06 PM]
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
As far as I know it is not guaranteed by the standard. With a std::vector it is also not guaranteed, but for almost every implementation I have come across, the storage has been contiguous. I have had the same experience with std::string (well, basic_string to be more precise). I wouldn't be surprised if there are some guarantees stated in the next standard, so people can be confident that they are writing portable code. Also, the contiguous storage allows for compatability with C functions.

Incidentally, may I ask why you are not using std::getline, defined in string?

Edit: OK, I started writing my reply when only one person had replied... I really need to pick up some speed.

[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || MSVC++ Library Fixes || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on September 2, 2003 7:52:51 PM]
[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || CUJ || MSVC++ Library Fixes || BarrysWorld || [email=lektrix@barrysworld.com]E-Mail Me[/email] ]
This can lead to horrible bugs if your implementation happens to be reference counted.

For example:
std::string one = "a string";std::string two = one; //one and two point to the SAME DATA.&*(one.begin()) = ''b''; // begin may or may not copy the data. Assigning to the iterator definitly will copy it. But you just bypassed it entirely. 


My code might be off; but you get the idea. Now, two might actually equal "b string".
quote:Original post by Deyja
For example:

std::string one = "a string";
std::string two = one; //one and two point to the SAME DATA.


No, this makes a copy. basic_string has an explicit constructor defined that is implemented so as to allocate separate memory.
quote:Original post by Deyja

&*(one.begin()) = 'b'; // begin may or may not copy the data. Assigning to the iterator definitly will copy it. But you just bypassed it entirely.


First thing's first, dereferencing the iterator returned by one.begin() will return a char, which you then get the address of, so you are trying to assign a (const) char to a char*, which is a conversion error. I think that you need to learn about how std::string works. The string associated with two would not be altered, as one and two have separate memory allocated for each other.

[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || MSVC++ Library Fixes || BarrysWorld || E-Mail Me ]

[edited by - Lektrix on September 2, 2003 8:21:08 PM]
[ Google || Start Here || ACCU || STL || Boost || MSDN || GotW || CUJ || MSVC++ Library Fixes || BarrysWorld || [email=lektrix@barrysworld.com]E-Mail Me[/email] ]
Actually, I think a vector might be garunteed to be continous.

But I''m pretty sure a string doesn''t have to be.

This topic is closed to new replies.

Advertisement