How to read any file safely into a string? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the best way to slurp a file into a std::string in c++?
I'm trying to imitate PHP's file_get_contents() function for C++.
However, when I convert a char array into a string, it stops at nullbyte:
fread(charbuf, 1, file_size, fp);
string str(charbuf);
How can I initialize the string as a static size array, and read the file contents directly to that container? Also, how do I check the errors for it, for example if there is not enough memory for initializing that string. This would also get me rid of the temporary memory allocation I'm currently using, which I would like to get rid of.
How about safety? Is it possible that many processes read the same file at same time and/or one of them writes in it at same time when I am reading it? How do I avoid such things happening?
I hope you can answer other way than "string isn't binary container".
I ask to reopen this question for the fact: "Apparently, this question is as relevant as ever: two years later, the two most efficient solutions still copy the whole file contents in memory, and this copy cannot be elided by the optimizer. This is a quite unsatisfactory state of affairs. – Konrad Rudolph Oct 25 '10 at 6:25" at What is the best way to read an entire file into a std::string in C++? Or do you want me to create new question that asks to read a file without having extra copy of the string?

std::ifstream fin("somefile.txt");
std::stringstream buffer;
buffer << fin.rdbuf();
std::string result = buffer.str();
This snippet will put all your file into std::string

I hope you can answer other way than "string isn't binary container.
std::string is a binary container, but the constructor you chose takes a C-style string as an argument. Try a different constructor:
std::fread(charbuf, 1, file_size, fp);
std::string str(charbuf, file_size);
EDIT: Taking into account requirement to avoid memory allocations:
std::string str(file_size, 0);
std::fread(&str[0], 1, file_size, fp);

Related

How to Duplicate a file pointer [duplicate]

This question already has answers here:
Duplicating file pointers?
(3 answers)
Closed 7 years ago.
I want to use fgets twice on the same stream. I have defined two file pointer pointing to the same file but when I use fgets on one of the pointer, the other also gets modified.
fun(FILE * input) {
FILE * input_dup=input;
char str[2];
fgets(str, 2, input);
fgets(str, 2, input_dup);
}
On the second call to fgets, why is it reading the next character.. It should give the same output as they both are pointing to the same location
Well, you are laboring under a fundamental mis-understanding:
If you copy a pointer, that does not copy the object it points to.
As it happens, there's no standard way for duplicating a FILE (though there are nonstandard ones, see: Duplicating file pointers?).
Which doesn't happen you are SOL, you can just use ftell to get the current position, and fseek to get back there (provided the stream is seekable, like a file).
As with all C++ coding, it is doing exactly what you told it to do. If you want another copy, you could make an overriding function that tells the system to read and act and copy the stream and return a pointer to an array. That would accomplish your goal.
Asecond solution would be to unget the stream's last char, then read again.

C++ strings vs vector<char> [duplicate]

This question already has answers here:
What are differences between std::string and std::vector<char>?
(5 answers)
C++: char test[100] vs array<char, 100> vs string
(4 answers)
Closed 7 years ago.
It's known to everyone of us that we should prefer string class in C++ for all string applications due to the many special functions they perform & their ability to grow & reduce dynamically. What string is for characters, vector is for other data types & classes because it shows great performance.
However is there any situation where we would need to prefer vector<char> (which I see seldom) over string ?
I'd use vector<char> only if I explicitly intent to store an array of char values, which is not a string. E.g. if for some reason I'd collect all the characters used somewhere in a specific text, the result might be a vector<char>.
To be clear: it is all about expressing the intent.
To put it briefly: if you're storing text, then string, otherwise vector<char>.

Convert std::string to char* debate [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
In C++ 98, is this a legitimate method to cast from a string to a char *?
char * n = (char *) someString.c_str();
(In my original wording, the function above was recommended by a senior programmer)
Namely, is it a better method than:
s2 = (char *)alloca(s0.size() + 1);
memcpy(s2, s0.c_str(), s0.size() + 1);
(courtesy of convert string to char*)
If so, why?
Use Case:
I need to use a char*, but I don't need to alter the data after it is in the char*. I'm passing it to a display library.
I'm just looking for a short and sweet answer. Thanks!
Edit: I changed the wording to this question because it got down voted. I hope my rewording makes it a better question. I think the answers were interesting and insightful.
For the record: Anyone interested in this question, should look at all the responses. I could only pick one, but I found them all interesting.
string::c_str() returns a const pointer to a null-terminated C-style string that contains the same contents as the original string. In most common implementations, c_str() simply returns a pointer to the string's internal data if it is not empty, but that is not required by the C++ standard.
If you just need to read the content of the string and not modify it, there is no need to allocate a separate buffer, just use c_str() by itself. The returned char* will remain valid as long as the string is not altered, either by the =/+=/[] operator, or the insert() or erase() method, or an iterator, etc.
If you need to modify the string via the char* pointer, then you have to allocate a separate buffer, copy the string content into it, modify it as needed, and then copy the new content back to the string using its own methods.
Your senior programmer is wrong. Casting away const-ness like that at the very least is wrong (no guarantees that it points to the actual memory of the string for example), and yields undefined behavior if the underlying objects happen to be const.
The answer here depends on whether you need a mutable string or just to be able to read it.
If all you want to do with your char* is to look at the contents then, as the comments have pointed out, you need to assign it to a const char* (and drop the cast).
Your method works, but if all you need to do is read the string, there is no point in copying it to a new location.
If you need to modify the string, then your copy would be appropriate. However, you need to be aware that changes will not be reflected in the original string.
First off, memcpy does not allocate memory. It only copies things from one place to another.
In C++ the idiom, using memcpy is:
std::string my_string = "California Needs Rain!\n";
char * p_text_string = new char [my_string.length() + 1U];
memcpy(p_text_string,
my_string.c_str(),
my_string.length());
// Add the nul terminator
p_text_string[my_string.length()] = '\0';
Remember that the memory allocated needs to be 1 more than the length of the string because of the nul, '\0', terminator character that needs to be appended.
The std::string is not required to be nul terminated.

How do I store a variable length string in C/C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the best way to slurp a file into a std::string in c++?
Im trying to store a whole text file as a string,
how can I dynamically store any amount of characters the text file may contain?
The C++ Standard Library provides the std::string type for dynamically sized strings. It is a typedef for std::basic_string<char>. There's a useful reference at cppreference.com.
For reading lines from a file into a std::string, take a look at std::getline. You can use it to get a line from a file as follows:
std::string str;
std::getline(file_stream, str);
Be sure to check the stream (it is returned by std::getline) to see if everything went okay. This is often done in a loop:
while (std::getline(file_stream, str)) {
// Use str
}
In addition to sftrabbit's answer:
Note that you can read a whole file into a string in one go by doing this:
std::ifstream input_ifstr(filename.c_str());
std::string str(
(std::istreambuf_iterator<char>(input_ifstr)),
std::istreambuf_iterator<char>());
input_ifstr.close();
You can construct a stringstream from it to process with getline afterwards if you wish.

Simple General Questions about C++ [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Ive moved from autoit and am now learning C++ and some problems keep coming up.
The first one is storing character input. The problem is that I have no idea how many characters are in that line of the file (if you are reading a file) or how many letters a user is going to type (in a console application).
What is the best way to approach this problem?? I have heard about the string class, but I want to avoid it becuase I dont know how it works and that leads to vunerabilities etc.
Secondly...
In C you can load shellcode into memory, create a function pointer, and execute that code.
Is there any mechanism for this in C++???
Thirdly...
How does the interpreter iterate through char arrays for string output??? (char array[3];) Does the compiler keep track of the size of the array, or does it just keep reading from memory until it hits that \0 thing???
Lastly...
If Char * are just pointers to data in memory, then why does:
char * title = "Program Title";
this work??? where is the string literal stored in memory?? how is it referenced???
Thankyou very much. I greatly appreciate your help.
-Hyperzap
Investing your time in learning std::string is well worth the effort, as it takes care of a lot of hassle for you. If you don't want to take advantage of the features in C++, then why use C++ and not just C?
You can use the same code for this as you would in C.
Yes, iostream-output of C-style strings outputs until terminating zero. Once again, if you use std::string you do not have to care about such details.
Correct me if I'm wrong, but I think title would be a const char[] stored on the stack.
Example:
const char* hello = "Hello\0World";
cout << hello; // Prints only "Hello", i.e. up to terminating zero (\0)
The reason this works:
const char* hello = "Hello world";
cout << hello;
is because hello is really "Hello world\0"; - in other words, the compiler inserts a terminating zero.
Note that std::string doesn't do any magic. It too reads until the terminating zero:
string hello = "Hello\0World\n";
cout << hello; // Still only gives "Hello"
char* title = "String Literal" works because the compiler preallocates a memory location to store your string literal, thus you then get back a pointer to this memory location.
In c++, an array for which you know the size at compile time (as in your example: char array[3] is a type in itself, so the compiler does keep track of the size. However, if you do not know the size (ie. char array[]), it is just a pointer to char. However, you should be using std::vector in c++ (better safety and performance).
I'm not too sure about your other two questions (didn't quite understand them)