Print a string with fprintf - c++

I am having an issue with printing a string which im using for debug purposes.
I create the string like so:
//checker is int
std::stringstream buttonx;
buttonx << "Button" << checker << "_x";
Now i try to print it to my error.txt file
FILE * p;
p = fopen ("error.txt","w");
fprintf(p, "%s" , buttonx.str());
fclose(p);
The output is:
,æ0
Its different every time. I'm not sure whats going on was hopeing some could explain the mistake?

fopen is plain C and cannot handle std::string. You need to input a char*, which you can access by calling .c_str() on the string, like this:
fprintf(p, "%s", buttonx.str().c_str());

the function fprintf wants a null terminated string (a C string); you need the c_str() instead of yours:
buttonx.c_str()

Related

how to make a new line in binary file c++?

Can anybody help me with this simple thing in file handling?
This is my code:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
int main()
{
fstream f;
f.open("input05.bin", ios_base::binary | ios_base::out);
string str = "";
cout << "Input text:"<<endl;
while (1)
{
getline(cin, str);
if (str == "end")
break;
else {
f.write((char*)&str, sizeof(str));
}
}
f.close();
f.open("input05.bin", ios_base::in | ios_base::binary);
while (!f.eof())
{
string st;
f.read((char*)&st, sizeof(st));
cout << st << endl;
}
f.close();
}
It is running successfully now. I want to format the output of the text file according to my way.
I have:
hi this is first program i writer this is an experiment
How can I make my output file look like the following:
hi this is first program
I writer this is an experiment
What should I do to format the output in that way?
First of all,
string str;
....
f.write((char*)&str, sizeof(str));
is absolutely wrong as you cast a pointer to an object of type std::string to a pointer to a character, i.e. char*. Note that an std::string is an object having data members like the length of the string and a pointer to the memory where the string content is kept, but it is not a c-string of type char *. Further, sizeof(str) gives you the size of the "wrapper object" with the length member and the pointer, but it does not give you the length of the string.
So it should be something like this:
f.write(str.c_str(), str.length());
Another thing is the os-dependant handling of new line character. Depending on the operating system, a new line is represented either by 0x0d 0x0a or just by 0x0d. In memory, c++ treats a new line always as a single character '\n'(i.e. 0x0d). When writing to a file in text mode, c++ will expand an '\n' to 0x0d 0x0a or just keep it as 0x0d (depending on the platform). If you write to a file in binary mode, however, this replacement will not occur. So if you create a file in binary mode and insert only a 0x0d, then - depending on the platform - printing the file in the console will not result in a new line.
Try to write ...
f.write(str.c_str(), str.length());
f.put('\r');
such that it will work on your platform (and will not work on other platforms then).
That's why you should write in text mode if you want to write text.

Parse from FILE structure to string in C++

I'm trying to capture a system command on Windows with the following code, to return the output as a string.
std::string exec(char* cmd) {
FILE* pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
std::ifstream ifs(pipe);
std::string content( (std::istreambuf_iterator<char>(ifs) ),
(std::istreambuf_iterator<char>() ) );
printf("%s", content);
return content;
}
When I call the function like this:
char *command = "set";
std::string results = exec(command);
printf("%s", results);
getchar();
The output is just a few random bytes.
╝÷:ö°:
I was trying to get all the results appended in 1 long string. Can anyone tell me what I'm doing wrong?
I tried redirecting the stderr to output with the command but it also gives some random bytes.
Since you're using printf() which knows nothing about C++ std::string values, you need to print the C string representation of the content:
printf("%s", content.c_str());
The printf() function was told to expect that, but it wasn't what you passed to it.
Or, as others pointed out, you should use the native C++ I/O:
std::cout << content;
Printf expects C string, char*.
Use
printf("%s",results.c_str());
Don't use printf, use the C++ standard output stream instead:
std::cout << content << '\n';

std::stringstream.str() outputs garbage

I need to save a bunch of image files with numbered indices. I am trying to construct these filenames using a stringstream. However, stringstream.str() does not seem to return the filename, but rather returns some garbage.
Here is the code:
std::stringstream filename;
filename << filepath << fileindex << ".png";
bool ret = imwrite(filename.str(),frame, compression_params);
fileindex++;
printf("Wrote %s\n", filename.str());
Here is the output from one execution:
Wrote ╠±0
Wrote ╠±0
Wrote ╠±0
Wrote ╠±0
Here is the output from another execution:
Wrote ░‗V
Wrote ░‗V
Wrote ░‗V
Wrote ░‗V
Any suggestions? Is imwrite is an opencv function, and I have [code]using namespace cv;[/code] at the top of the file - is there some interference between opencv and std?
You can't pass a non-POD type like std::string to a C-style variadic function like printf.
You could use C++ output:
std::cout << "Wrote " << filename.str() << '\n';
or, if you like old-school weirdness, extract the C-style string for C-style output:
printf("Write %s\n", filename.str().c_str());
filename.str() returns a std::string object. You can't printf it directly. Format %s requires C-style string. This should work
printf("Wrote %s\n", filename.str().c_str());
In any case, using C-style functions with C++ objects is not always the best idea.

Access from map, casting string to char*

I have the following problem with casting (or accessing data, I'm not sure):
There is map<int, string> keys I use to describe buttons, number matches the Allegro5 key code (eg. keys[81] = "PgDown"). I want to print data on the screen using al_draw_text, which needs char* parameter to be passed.
I tried access data this way:
char dropdownBuffer[16];
cout << keys[dropdownKeyCode] << endl;
sprintf_s(dropdownBuffer, "%s", keys[dropdownKeyCode]);
cout << dropdownBuffer << endl;
gui.drawButton(CLIENT_PADDING, CLIENT_PADDING+50+219, 123, 38, dropdownBuffer);
Console should print string Spacja twice, but second time there are some random chars.
What am I doing wrong now? Maybe there is other possible way to cast this string to char?
to get pointer to data from string, use c_str(), see ref: this
replace code:
sprintf_s(dropdownBuffer, "%s", keys[dropdownKeyCode]);
with:
sprintf_s(dropdownBuffer, "%s", keys[dropdownKeyCode].c_str());
I thought sprintf_s needs a sizeof argument.
sprintf_s(dropdownBuffer, sizeof(dropdownBuffer), "%s", keys[dropdownKeyCode]);
or
const char* dropdownBuffer = keys[dropdownKeyCode].c_str();

Delete a part of a file?

I have want to code a program that functions to open a file and if I find "Hello World", the program will automatically copy the text before "Hello World" in to a new file.
The problem is, how could I delete the text 'hello world' in the 'buffer', for example :
buffer = new char [Size];
ifstream fstr;
fstr.open(path, ios::in);
fstr.read(buffer, (Size));
fstr.close();
//what should i write here about copying the rest of the text except
//Hello World?
ofstream outputFile(path2, ios::out);
outputFile << buffer;
outputFile.close();
Thank you for helping me :) Btw I'm using Borland C++ and I'm a learner.
Assuming the file is all text you could use strstr to find "Hello World" and then set the end of the string.
char *Found = strstr(buffer, "Hello World");
if (Found != NULL)
*Found = 0;
First some gotcha! type issues.
What if the file doesn't contain "Hello World"?
What if it contains "Hello World"?
What if it contains "Hello World", but the "World" starts on the next line?
I don't have the answer to these. That's up to you, and your instructor if this is homework.
Now a suggestion: Use C++ strings (std::string) rather than C-style strings.
In C you could call strstr to find the location of that string. If found, either write a 0 at the found location, or strcpy the empty string to the found location.
In C++ you can find the location of the target string with the member function find. If found, erase the stuff at and after the found location with the member function erase.
Which function / member names makes more sense? Which method of erasing from "Hello World" on makes more sense? Which code would you rather come back to six months from now?