Just trying a programming test for fun. It stipulates that I should read each word of a file, one by one.
It hints that I might want to use ifstream, but won't let me use std::string, so it looks like I have to use char*
In C I would read line by line & use strok() as I have multiple delimiters (white-space, quotes, brackets, etc).
What the most C++ way to do this - get the words one by one - without using std::string ?
First you must make sure that you have memory allocated for your string (this part would be handled automatically by std::string). Then just use the normal input operator >>, as it will separate on whitespace.
Don't forget to free the memory you allocate (also handled automatically by std::string).
Lesson to be learned: Use char pointers for exercises like these, otherwise use std::string.
Just read the file into a std::string and then use std::string::c_str ( ) to retrive the nul-terminated C-style string from std::string object.
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.
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.
I have an external_jpeg_func() that takes jpeg data in a char array to do stuff with it. I am unable to modify this function. In order to provide it the char array, I do something like the following:
//what the funcs take as inputs
std::string my_get_jpeg();
void external_jpeg_func(const char* buf, unsigned int size);
int main ()
{
std::string myString = my_get_jpeg();
external_jpeg_func(myString.data(), myString.length() );
}
My question is: Is it safe to use a string to transport the char array around? Does jpeg (or perhaps any binary file format) be at risk of running into characters like '\0' and cause data loss?
My recommendation would be to use std::vector<char>, instead of std::string, in this case; the danger with std::string is that it provides a c_str() function and most developers assume that the contents of a std::string are NUL-terminated, even though std::string provides a size() function that can return a different value than what you would get by stopping at NUL. That said, as long as you are careful to always use the constructor that takes a size parameter, and you are careful not to pass the .c_str() to anything, then there is no problem with using a string here.
While there is no technical advantage to using a std::vector<char> over a std::string, I feel that it does a better job of communicating to other developers that the content is to be interpreted as an arbitrary byte sequence rather than NUL-terminated textual content. Therefore, I would choose the former for this added readability. That said, I have worked with plenty of code that uses std::string for storing arbitrary bytes. In fact, the C++ proto compiler generates such code (though, I should add, that I don't think this was a good choice for the readability reasons that I mentioned).
std::string does not treat null characters specially, unless you don't give it an explicit string length. So your code will work fine.
Although, in C++03, strings are technically not required to be stored in contiguous memory. Just about every std::string implementation you will find will in fact store them that way, but it is not technically required. C++11 rectifies this.
So, I would suggest you use a std::vector<char> in this case. std::string doesn't buy you anything over a std::vector<char>, and it's more explicit that this is an array of characters and not a possibly printable string.
I think it is better to use char array char[] or std::vector<char>. This is standard way to keep images. Of course, binary file may contain 0 characters.
I have the following code:
char myText[256];
cin.getline(myText,256);
Why exactly do I have to pass a character array to cin.getline() and not a string?
I have read that in general it is better to use strings than character arrays. Should I then convert a character array to a string after retrieving input with cin.getline(), if that is possible?
You are using the member method of istream. In this case cin. This function's details can be found here :
http://en.cppreference.com/w/cpp/io/basic_istream/getline
However you could use std::getline
Which uses a string instead of a char array. It's easier to use string since they know their sizes, they auto grow etc. and you don't have to worry about the null terminating character and so on. Also it is possible to convert a char array to a string by using the appropriate string contructor.
That's an unfortunate historical artifact, I believe.
You can however, use the std::getline free function instead.
std::string myText;
std::getline(std::cin,myText);
Im having a bit of trouble reading CSVs. I have multiple types of data, so i am not sure how to get this to work:
string, string, bool, bool, int
I cant simply use >> to read in the data since the deliminator is not whitespace. scanf doesnt work, since it needs a human input, not file input, getline only reads in strings and also includes the \n char for some reason.
how can i read my csv properly?
You CAN use getline. There's an overload where the third argument passed can be a char for the delimiter. Just throw it all in a loop
Another option (which isn't typically recommended for C++, though), is fscanf. You're right that scanf is no good for you, but fscanf is its file-based equivalent.
Another canonical solution typically employed in C, but which isn't so strongly recommended in C++, is to go ahead and use getline, and then use strtok or a simple parser to parse each line.