Why fprintf() function in my code don't working properly? - c++

First fprintf() works as it has to work, but second output whole nonsense
#include <string>
int main()
{
FILE* f;
fopen_s(&f, "text.txt", "w");
std::string name = "hello";
int area = 123;
char ch = 'i';
fprintf(f, "abc"); // OK
fprintf(f, "|%-12s |%-5c |%-9d |", name.c_str(), area, ch); // not OK
}

The %s format specifier expects a null-terminated array of char, not std::string. Thus the fprintf's behavior is undefined.
Use:
fprintf(f, "|%-12s |%-5c |%-9d |", name.c_str(), area, ch);
as the c_str() function returns the null-terminated array.
In addition, the format strings for the other types also seem incorrect. To print an int, the format specifier is %d, not %c, and the format specify for char is %c, not %d.
Thus the final call to fprintf should be:
fprintf(f, "|%-12s |%-5d |%-9c |", name.c_str(), area, ch);

Related

Convert char pointer hex to a string and save in text file C++

I create a dll that is injected in a process and return a hex value for example : 570AC400. I have a function of type __int64 GetLocalPlayer_EX() that return this hex values, but text saved in txt return strange string like #*░B
char *ptr = reinterpret_cast<char*>(GetLocalPlayer_EX());//GetLocalPlayer_EX() is function return hex value
std::string str(ptr);
printf("LocalPlayer = %s\n", ptr);//print to test, but return strange string like #*░B should be 570AC400
void WriteLogFile(const char* szString)//convert char hex to string and save in txt
{
FILE* pFile = fopen("C:\\TesteArquivo\\TesteFile.txt", "a");
fprintf(pFile, "%s\n", szString);
fclose(pFile);
}
WriteLogFile(vOut); // call function to save txt file
PS: if I use printf("LocalPlayer =%I64X\n", ptr);, the return hex value is correct.
You get the raw int back from the function. You shouldn't cast it to a char*. Try this:
__int64 rv = GetLocalPlayer_EX();
printf("LocalPlayer = %ld\n", rv);
printf("LocalPlayer = %X\n", rv);
but I wonder if the signature of the function is correct. Does it really return __int64 and not a ClientPlayer* ?
Edit:
Since it seems to be a pointer in disguise,
char *ptr = reinterpret_cast<char*>(GetLocalPlayer_EX());
printf("%p\n", ptr);

Junk values in ofstream using strncpy

I am running the following program below. I am taking the first 63 char values in B.txt and then attaching the float values in A.txt, beginning at the 62nd column in A.txt, at the end of the lines of B.txt
So if B.txt contains:
I am running the following program below. I am taking the firstXXXXXXXX
and A.txt contains:
I am running the following program below. I am taking the fir3.14
I want B.txt to look like:
I am running the following program below. I am taking the first3.14
However, the output I'm getting instead is:
I am running the following program below. I am taking the firstBUNCH OF JUNK3.14
int main()
{
loadfileB("B.txt");
return 0;
}
void loadfileB(char* fileName)
{
FILE* fp = fopen(fileName, "r");
char line[82];
vector<int> rownum;
vector<float> temp;
temp = loadfileA("A.txt");
int i = 0;
ofstream fout("output.txt");
while (fgets(line, 81, fp) != 0)
{
radius=temp[i];
char buffer[64];
strncpy(buffer, line, 63);
fout << buffer<< " " << radius << endl;
i++;
}
fclose(fp);
}
vector<float> loadfileA(char* fileName)
{
FILE* fp = fopen(fileName, "r");
char line[82];
vector<int> rownum;
vector <float> tempvec;
int i = 0;
while (fgets(line, 81, fp) != 0)
{
float temp;
getFloat(line, &temp, 60, 6);
tempvec.push_back(temp);
}
fclose(fp);
return tempvec;
}
void getFloat(char* line, float* d, int pos, int len)
{
char buffer[80];
*d = -1;
strncpy(buffer, &line[pos], len);
buffer[len] = '\0';
sscanf(buffer, "%f", d);
}
strncpy is a bad function to use. This is because it does not null-terminate its output if the input did not fit in the buffer. The garbage you are seeing is the result of passing a non-null-terminated buffer to a function that expected a null-terminated string.
The simplest fix is to replace:
char buffer[64];
strncpy(buffer, line, 63);
with:
std::string buffer = line;
buffer.resize(63);
In your other usage you do null-terminate, however you never check that len is smaller than 80 either. Again the simpler fix would be:
std::string buffer( line + pos, len );
sscanf(buffer.c_str(), "%f", d);
The getFloat function should have some way of signaling error (either a return value; or throw an exception if sscanf does not return 1).
Of course, you could replace a lot of your other C-style code with C++-style code too and avoid buffer size issues entirely.

stack check fail in sha-1 c++

I'm having a __stack_chk_fail in the main thread.
I have no idea why is this happening?
I got the codes from this website:
http://www.packetizer.com/security/sha1/
Im trying to add a function to compute the digest of a file using the example.
.h file
#include <stdio.h>
#include <string>
std::string digestFile( char *filename );
.cpp file
std::string SHA1::digestFile( char *filename )
{
Reset();
FILE *fp = NULL;
if (!(fp = fopen(filename, "rb")))
{
printf("sha: unable to open file %s\n", filename);
return NULL;
}
char c = fgetc(fp);
while(!feof(fp))
{
Input(c);
c = fgetc(fp);
}
fclose(fp);
unsigned message_digest[5];
if (!Result(message_digest))
{ printf("sha: could not compute message digest for %s\n", filename); }
std::string hash;
for (int i = 0; i < 5; i++)
{
char buffer[8];
int count = sprintf(buffer, "%08x", message_digest[i]);
if (count != 8)
{ printf("converting unsiged to char ERROR"); }
hash.append(buffer);
}
return hash;
}
__stack_chk_fail occurs when you write to invalid address.
It turns out you do:
char buffer[8];
int count = sprintf(buffer, "%08x", message_digest[i]);
C strings are NUL-terminated. That means that when sprintf writes 8 digits, it adds 9-th char, '\0'. But buffer only has space for 8 chars, so the 9-th goes past the end of the buffer.
You need char buffer[9]. Or do it the C++ way with std::stringstream, which does not involve any fixed sizes and thus no risk of buffer overrun.

C++ Error STATUS_ACCESS_VIOLATION

I'm getting that error by running this simplest code:
#include "stdio.h"
#include "stdlib.h"
int main()
{
FILE* in;
FILE* out;
in = fopen("foo.in", "r");
out = fopen("bar.out", "w+");
int something;
fscanf(in, "%i", something);
fprintf(out, "%i", something);
fclose(in);
fclose(out);
return 0;
}
I'm running it out of Sublime Text 3.
fscanf expects a pointer, meaning that it modify the value of something while in the function fscanf if you send it by copy the value will be correct while in scope (i.e. while in fscanf) but the result is never returned so your copy of something is never changes, (i.e. it's still not initialized).
so what you need to do:
int something;
fscanf(in, "%i", &something);
fprintf(out, "%i", something);
and it should work, if you are trying to read an integer from foo.in and write it to bar.out.

C++, SQLite - pointer to pointer to string

I work with C++ and SQLite3 (with Microsoft Visual C++ 2008) and would like to read a value from my database and store it in a variable to work with it on.
The select statement works fine, but every time I viewed the callback function and try to read the value from char **argv, I get "only" the memory address, or the first ASCII character of the value, which is in the database. What am I doing wrong?
Here is the callback function:
static int callback(void *pArg, int argc, char **argv, char **azColName)
{
fprintf(f, "Callback aufgerufen!\n");
int i;
for(i=0; i<argc; i++)
{
fprintf(f, azColName[i]);
fprintf(f, " = ");
if(argv[i]){
fprintf(f, argv[i]);
//unsigned int x = argv[i];
}
else
fprintf(f, "NULL");
fprintf(f, "\n");
}
fprintf(f, "\n");
return 0;
}
I tried it without the callback function, but again I get the same result and I've tried different ways to store the value in a variable.
while (sqlite3_step(stmt) == SQLITE_ROW)
{
fprintf(f, "%s\n", sqlite3_column_text(stmt, 0));
//const unsigned char *c = sqlite3_column_text(stmt, 0);
fprintf(f, "%u\n", sqlite3_column_int(stmt, 0));
//unsigned int z = *sqlite3_column_int(stmt, 0);
stmt_count++;
}
Is it perhaps not possible to access the value or to store it in a variable?
I don't see why you need a callback - this should work (depending on the size of the data):
char myvalue[100];
while (sqlite3_step(stmt) == SQLITE_ROW)
{
strcpy( myvalue, (const char *) sqlite3_column_text(stmt, 0) );
// do something with myvalue
stmt_count++;
}