c++ string concatenation second time - c++

I am a newbie, writing a c++ code to open and read from multiple files and then dump part of the data into other files.
I want to generate file names in a for loop.
But I can't concatenate string(numbering of file) and string literal(a file extension). The same line of code works at the very beginning of the program, but not at the later part.
int main(int argc, char *argv[])
{
std::cout << std::string("9") + ".dat" << std::endl;
// many more lines
dump = 1;
if (dump == 1){
for (int ilevel=std::max(levelmin,lmin); ilevel < lmax + 1; ilevel++){
std::cout << std::string("9") + ".dat" << std::endl; // crashes here!
std::ofstream fout (std::string("9") + ".dat", std::ios::out | std::ios::binary);
std::cout << grid[ilevel].cube[0] << std::endl;
fout.write ((char*)&grid[ilevel].cube[0], grid[ilevel].cube.size() * sizeof(grid[ilevel].cube[0]));
fout.close();
}
}
...
}
If I put std::cout << std::string("9") + ".dat" << std::endl; at the beginning, it works and prints "9.dat".
but in the later loop, segmentation fault.
In between I call a function that uses stringstream to pad leading zeros to an integer. The function looks:
std::string int2str(const int n, const int m){
std::stringstream ss;
ss << std::setfill('0') << std::setw(m) << n;
std::string s2(ss.str());
ss.clear();
return s2;
}
I don't have a clear understanding about string and stringstream in c++.
But out of many things in my program, this function is the only thing I can think of being relevant. Other parts of codes does not deal with strings. It's mostly array manipulation code.
I've also tried std::string("9") + std::string(".dat")
but had no luck.
What is wrong?

Is there a specific reason why you're using std::string("9") rather than just "9"?
Where does the 9 come from? If its generated as part of a loop or a returned value from a function you can either place the variable itself to be concatenated, or the function that returns it, so:
std::cout << iFileNumber + ".dat" << std::endl;
or
std::cout << fileNumberGenerator() + ".dat" << std::endl;
For the hardcoded examples you've provided, I personally can't see the need for anything other than
std::cout << 9 + ".dat" << endl;
but that could easily just be lack of experience on my part.
For the sake of printing to the command line, its also worth nothing that this is equally acceptable syntax (assuming you're not already aware):
std::cout << 9 << ".dat" << endl;

Related

Why does ifstream read() behave differently in two different programs?

I'm trying to write a program that reads in an OpenGL shader from a .txt file. I've actually already done this a few days ago, this was the code I used:
char vShaderData[2000];
char fShaderData[2000];
void readShaders() {
std::ifstream vShaderF;
std::ifstream fShaderF;
vShaderF.open("shaders//vertexShader.txt");
fShaderF.open("shaders//fragShader.txt");
if (vShaderF.is_open() && fShaderF.is_open()) std::cout << m << "Shader read success" << std::endl;
else std::cout << "Shader read fail" << std::endl;
std::cout << m << "vertex shader: " << std::endl;
vShaderF.read(vShaderData, 2000);
for (int i = 0; i < 2000; i++) {
std::cout << vShaderData[i];
}
std::cout << std::endl << std::endl;
std::cout << m << "frag shader: " << std::endl;
fShaderF.read(fShaderData, 2000);
for (int i = 0; i < 2000; i++) {
std::cout << fShaderData[i];
}
std::cout << std::endl;
vShaderF.close();
fShaderF.close();
}
This worked great. my shader file was not actually not 2000 in length, but the read() call seemed to store the extra characters as whitespace into the char array which is what I wanted.
Now having restructured my code a little bit in a newer program, my reader now looks like this:
std::ifstream shaderFile;
shaderFile.open(path);
if (shaderFile.is_open()) cout << "Shader at: " << path << ", initalized" << endl;
char data[2000];
shaderFile.read(data, 2000);
for (int i = 0; i < 2000; i++) std::cout << data[i];
The actual text portion still reads correct. However, now the extra space in the char array is stored with this instead of whitespace:
In case the image won't show, it is basically just a reapeating pattern of these two characters [|[|[|....
Why is this happening and how can I fix it?
NOTE: I'm using the same shader file, same computer, same IDE, same everything. The old one still works.
When using std::istream:read() it will not set the parts of the buffer to spaces which were not read. The memory will be left untouched. If you want to get spaces into an unread area of the buffer, you'll need to put the spaces there yourself. If the program indeed had spaces in the buffer it was because the buffer somehow already contained spaces by chance.
You can use std::istream::gcount() to determine how many characters were read.
If you want the arrays to contain predefined data, you'll have to initialize it with such predefined data. If the stream reads fewer data than the array size, you will have the padding you want.

C++ equivalent of C fgets

I am looking to find a C++ fstream equivalent function of C fgets. I tried with get function of fstream but did not get what I wanted. The get function does not extract the delim character whereas the fgets function used to extract it. So, I wrote a code to insert this delim character from my code itself. But it is giving strange behaviour. Please see my sample code below;
#include <stdio.h>
#include <fstream>
#include <iostream>
int main(int argc, char **argv)
{
char str[256];
int len = 10;
std::cout << "Using C fgets function" << std::endl;
FILE * file = fopen("C:\\cpp\\write.txt", "r");
if(file == NULL){
std::cout << " Error opening file" << std::endl;
}
int count = 0;
while(!feof(file)){
char *result = fgets(str, len, file);
std::cout << result << std::endl ;
count++;
}
std::cout << "\nCount = " << count << std::endl;
fclose(file);
std::fstream fp("C:\\cpp\\write.txt", std::ios_base::in);
int iter_count = 0;
while(!fp.eof() && iter_count < 10){
fp.get(str, len,'\n');
int count = fp.gcount();
std::cout << "\nCurrent Count = " << count << std::endl;
if(count == 0){
//only new line character encountered
//adding newline character
str[1] = '\0';
str[0] = '\n';
fp.ignore(1, '\n');
//std::cout << fp.get(); //ignore new line character from stream
}
else if(count != (len -1) ){
//adding newline character
str[count + 1] = '\0';
str[count ] = '\n';
//std::cout << fp.get(); //ignore new line character from stream
fp.ignore(1, '\n');
//std::cout << "Adding new line \n";
}
std::cout << str << std::endl;
std::cout << " Stream State : Good: " << fp.good() << " Fail: " << fp.fail() << std::endl;
iter_count++;
}
std::cout << "\nCount = " << iter_count << std::endl;
fp.close();
return 0;
}
The txt file that I am using is write.txt with following content:
This is a new lines.
Now writing second
line
DONE
If you observe my program, I am using fgets function first and then using the get function on same file. In case of get function, the stream state goes bad.
Can anyone please point me out what is going wrong here?
UPDATED: I am now posting a simplest code which does not work at my end. If I dont care about the delim character for now and just read the entire file 10 characters at a time using getline:
void read_file_getline_no_insert(){
char str[256];
int len =10;
std::cout << "\nREAD_GETLINE_NO_INSERT FUNCITON\n" << std::endl;
std::fstream fp("C:\\cpp\\write.txt", std::ios_base::in);
int iter_count = 0;
while(!fp.eof() && iter_count < 10){
fp.getline(str, len,'\n');
int count = fp.gcount();
std::cout << "\nCurrent Count = " << count << std::endl;
std::cout << str << std::endl;
std::cout << " Stream State : Good: " << fp.good() << " Fail: " << fp.fail() << std::endl;
iter_count++;
}
std::cout << "\nCount = " << iter_count << std::endl;
fp.close();
}
int main(int argc, char **argv)
{
read_file_getline_no_insert();
return 0;
}
If wee see the output of above code:
READ_GETLINE_NO_INSERT FUNCITON
Current Count = 9
This is a
Stream State : Good: 0 Fail: 1
Current Count = 0
Stream State : Good: 0 Fail: 1
You would see that the state of stream goes Bad and the fail bit is set. I am unable to understand this behavior.
Rgds
Sapan
std::getline() will read a string from a stream, until it encounters a delimiter (newline by default).
Unlike fgets(), std::getline() discards the delimiter. But, also unlike fgets(), it will read the whole line (available memory permitting) since it works with a std::string rather than a char *. That makes it somewhat easier to use in practice.
All types derived from std::istream (which is the base class for all input streams) also have a member function called getline() which works a little more like fgets() - accepting a char * and a buffer size. It still discards the delimiter though.
The C++-specific options are overloaded functions (i.e. available in more than one version) so you need to read documentation to decide which one is appropriate to your needs.

Save Int Data into Text File in C++

I working on saving Data into text file and compare it with another text file. Below is the code I worked on:
ofstream outfile;
outfile.open("Data",ios::out | ios :: binary);
for(x=0; x<100; x++)
{
printf("data- %x\n", *(((int*)pImagePool)+x));
int data = *(((int*)pImagePool)+x);
//outfile<<(reinterpret_cast<int *>(data))<<endl;
outfile<<(int *)data<<endl;
}
The result from printf is 24011800 and result read from text file is 0x24011800
Why there is 0x appeared? Do we able to remove it?
What is the difference between reinterpret_cast<int *> & (int *) but both giving the same result?
It's because you cast it as a pointer, so the output will be a pointer.
Since data is a normal value variable, just write it as usual:
outfile << data << '\n';
I also recommend you stop using printf when programming C++, there no reason to use it. Instead output using std::cout:
std::cout << "data- " << *(((int*)pImagePool)+x) << '\n';
Or if you want hexadecimal output
std::cout << "data- " << std::hex << *(((int*)pImagePool)+x) << '\n';
"%x" is a specifier for a hexadecimal number. Check this table: http://www.cplusplus.com/reference/cstdio/printf/
Use "%d" to output a decimal.
EDIT: About the casting, see this:
Reinterpret_cast vs. C-style cast
This is a very simple example using the ofstream f. The most complicated part are the parameters passed to the open, specifically std::ios::out which specifies the file direction. You could also use std::ios:in for reading from a file along with cin.
// ex5.cpp
#include <string>
#include <iostream>
#include <fstream>
#include "hr_time.hpp"
#include >ios>
int main(int argc, char * argv[])
{
CStopWatch sw;
sw.startTimer() ;
std::ofstream f;
f.open("test.txt",std::ios::out ) ;
for (int i=0;i<100000;i++)
{
f << "A very long string that is number " << i << std::endl;
}
f.close() ;
sw.stopTimer() ;
std::cout << "This took " << sw.getElapsedTime() << " seconds" << std::endl;
return 0;
}

C++ Stringstream int to string but returns null

Hi below is my function:
string Employee::get_print(void) {
string out_string;
stringstream ss;
ss << e_id << " " << type << endl;
out_string = ss.str();
return out_string;
}
e_id and type are int and they contain values from the class Employee. But when I pass them into the stringstream they just clear the string when I try to out put it. But if I don't have a int in the ss << "Some text" << endl; this output fine. What am I doing wrong =S
//Edit
Ok;
This is the calling code:
tmp = cur->get_print();
Where tmp is a string and cur is an Employee Object.
This code...
stringstream out;
out << "Test " << e_id << " " << e_type;
return out.str();
Retruns "Test " and nothing else. If I take out "Test " << my returned string is ""
I'm using GCC 4.2 on Mac OS/X 10.6.2 if that makes any difference.
I too am unable to reproduce this error. As has been mentioned, don't include the endl, as this actually appends a \n and is supposed to flush the write buffer. For this use, it is completely unnecessary and may actually lead to undesirable results...However, the code in your edit/update works just fine for me.
int main(int argc, char* argv[])
{
int e_id = 5;
int e_type = 123456;
stringstream out;
out << "Test " << e_id << " " << e_type;
cout << out.str();
return 0;
}
Produces:
Test 5 123456
My suggestions would be to double check that e_id and e_type are really just native int.
For further testing, you may want to force a cast on the values to see if it helps as such:
out << "Test " << (int)e_id << " " << (int)e_type;
Since I'm unable to reproduce this error, I'm afraid I'm unable to help any further. But best of luck to you!
Ok I have no idea what is going on with stringstream I've tried using it in other parts of my code and it doesn't work with integers. Therefore, I have reverted to using the sprintf C function:
string Employee::get_print(void) {
char out[50];
sprintf(out, "%d %d", e_id, e_type);
string output = out;
return output;
}
This returns the string which is needed.
I have moved into Netbeans and I don't have this problem. So it is an issue with Xcode.
I think the endl is not needed. You only need to write endl if you want to write a newline on a file on on std::cout.
Since you write endl, your stringstream will contain a string with 2 lines of which the second is empty. This probably confuses you. Remove the endl to get only one line.
I've got exactly the same problem - GCC and stringstream returning nothing.
As I found out, the trick is that you have to put some text data before anything else into the stringstream.
This code...
stringstream ss(stringstream::out);
ss << 3.14159;
cout << "'" << ss.str() << "'" << endl;
gets you this result:
''
But if we put a single "" inside the stringstream first...
stringstream ss(stringstream::out);
ss << "" << 3.14159;
cout << "'" << ss.str() << "'" << endl;
the result is as expected:
'3.14159'

How do you append an int to a string in C++? [duplicate]

This question already has answers here:
How to concatenate a std::string and an int
(25 answers)
Closed 6 years ago.
int i = 4;
string text = "Player ";
cout << (text + i);
I'd like it to print Player 4.
The above is obviously wrong but it shows what I'm trying to do here. Is there an easy way to do this or do I have to start adding new includes?
With C++11, you can write:
#include <string> // to use std::string, std::to_string() and "+" operator acting on strings
int i = 4;
std::string text = "Player ";
text += std::to_string(i);
Well, if you use cout you can just write the integer directly to it, as in
std::cout << text << i;
The C++ way of converting all kinds of objects to strings is through string streams. If you don't have one handy, just create one.
#include <sstream>
std::ostringstream oss;
oss << text << i;
std::cout << oss.str();
Alternatively, you can just convert the integer and append it to the string.
oss << i;
text += oss.str();
Finally, the Boost libraries provide boost::lexical_cast, which wraps around the stringstream conversion with a syntax like the built-in type casts.
#include <boost/lexical_cast.hpp>
text += boost::lexical_cast<std::string>(i);
This also works the other way around, i.e. to parse strings.
printf("Player %d", i);
(Downvote my answer all you like; I still hate the C++ I/O operators.)
:-P
These work for general strings (in case you do not want to output to file/console, but store for later use or something).
boost.lexical_cast
MyStr += boost::lexical_cast<std::string>(MyInt);
String streams
//sstream.h
std::stringstream Stream;
Stream.str(MyStr);
Stream << MyInt;
MyStr = Stream.str();
// If you're using a stream (for example, cout), rather than std::string
someStream << MyInt;
For the record, you can also use a std::stringstream if you want to create the string before it's actually output.
cout << text << " " << i << endl;
Your example seems to indicate that you would like to display the a string followed by an integer, in which case:
string text = "Player: ";
int i = 4;
cout << text << i << endl;
would work fine.
But, if you're going to be storing the string places or passing it around, and doing this frequently, you may benefit from overloading the addition operator. I demonstrate this below:
#include <sstream>
#include <iostream>
using namespace std;
std::string operator+(std::string const &a, int b) {
std::ostringstream oss;
oss << a << b;
return oss.str();
}
int main() {
int i = 4;
string text = "Player: ";
cout << (text + i) << endl;
}
In fact, you can use templates to make this approach more powerful:
template <class T>
std::string operator+(std::string const &a, const T &b){
std::ostringstream oss;
oss << a << b;
return oss.str();
}
Now, as long as object b has a defined stream output, you can append it to your string (or, at least, a copy thereof).
Another possibility is Boost.Format:
#include <boost/format.hpp>
#include <iostream>
#include <string>
int main() {
int i = 4;
std::string text = "Player";
std::cout << boost::format("%1% %2%\n") % text % i;
}
Here a small working conversion/appending example, with some code I needed before.
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main(){
string str;
int i = 321;
std::stringstream ss;
ss << 123;
str = "/dev/video";
cout << str << endl;
cout << str << 456 << endl;
cout << str << i << endl;
str += ss.str();
cout << str << endl;
}
the output will be:
/dev/video
/dev/video456
/dev/video321
/dev/video123
Note that in the last two lines you save the modified string before it's actually printed out, and you could use it later if needed.
For the record, you could also use Qt's QString class:
#include <QtCore/QString>
int i = 4;
QString qs = QString("Player %1").arg(i);
std::cout << qs.toLocal8bit().constData(); // prints "Player 4"
cout << text << i;
One method here is directly printing the output if its required in your problem.
cout << text << i;
Else, one of the safest method is to use
sprintf(count, "%d", i);
And then copy it to your "text" string .
for(k = 0; *(count + k); k++)
{
text += count[k];
}
Thus, you have your required output string
For more info on sprintf, follow:
http://www.cplusplus.com/reference/cstdio/sprintf
cout << text << i;
The << operator for ostream returns a reference to the ostream, so you can just keep chaining the << operations. That is, the above is basically the same as:
cout << text;
cout << i;
cout << "Player" << i ;
cout << text << " " << i << endl;
The easiest way I could figure this out is the following..
It will work as a single string and string array.
I am considering a string array, as it is complicated (little bit same will be followed with string).
I create a array of names and append some integer and char with it to show how easy it is to append some int and chars to string, hope it helps.
length is just to measure the size of array. If you are familiar with programming then size_t is a unsigned int
#include<iostream>
#include<string>
using namespace std;
int main() {
string names[] = { "amz","Waq","Mon","Sam","Has","Shak","GBy" }; //simple array
int length = sizeof(names) / sizeof(names[0]); //give you size of array
int id;
string append[7]; //as length is 7 just for sake of storing and printing output
for (size_t i = 0; i < length; i++) {
id = rand() % 20000 + 2;
append[i] = names[i] + to_string(id);
}
for (size_t i = 0; i < length; i++) {
cout << append[i] << endl;
}
}
There are a few options, and which one you want depends on the context.
The simplest way is
std::cout << text << i;
or if you want this on a single line
std::cout << text << i << endl;
If you are writing a single threaded program and if you aren't calling this code a lot (where "a lot" is thousands of times per second) then you are done.
If you are writing a multi threaded program and more than one thread is writing to cout, then this simple code can get you into trouble. Let's assume that the library that came with your compiler made cout thread safe enough than any single call to it won't be interrupted. Now let's say that one thread is using this code to write "Player 1" and another is writing "Player 2". If you are lucky you will get the following:
Player 1
Player 2
If you are unlucky you might get something like the following
Player Player 2
1
The problem is that std::cout << text << i << endl; turns into 3 function calls. The code is equivalent to the following:
std::cout << text;
std::cout << i;
std::cout << endl;
If instead you used the C-style printf, and again your compiler provided a runtime library with reasonable thread safety (each function call is atomic) then the following code would work better:
printf("Player %d\n", i);
Being able to do something in a single function call lets the io library provide synchronization under the covers, and now your whole line of text will be atomically written.
For simple programs, std::cout is great. Throw in multithreading or other complications and the less stylish printf starts to look more attractive.
You also try concatenate player's number with std::string::push_back :
Example with your code:
int i = 4;
string text = "Player ";
text.push_back(i + '0');
cout << text;
You will see in console:
Player 4
You can use the following
int i = 4;
string text = "Player ";
text+=(i+'0');
cout << (text);
If using Windows/MFC, and need the string for more than immediate output try:
int i = 4;
CString strOutput;
strOutput.Format("Player %d", i);