How is the file offset advanced by fstream::read? [duplicate] - c++

This question already has answers here:
tellg() function give wrong size of file?
(4 answers)
Closed 3 years ago.
#include <fstream>
#include <iostream>
int main(int argc, char * argv [])
{
std::ifstream f{ "test.syp" };
std::cout << f.tellg() << '\n';
char buffer[4];
f.read(buffer, 4);
std::cout << f.gcount() << '\n';
std::cout << f.tellg() << '\n';
}
When I execute the above code, I get the following output:
0
4
20
If I change ifstream to fstream, I get the same thing except that the last number is 21.
I would expect the last number to be 4 in both instances. Why isn't it?
Edit: I get the expected result if I open the file with std::ios::binary; it must be a quirk of text-mode

f.gcount returns the number of characters read by the last unformatted input operation (in this case, f.read()).
f.tellg() returns an input position indicator; that's an opaque value that has meaning to seekg(), but its numeric value isn't meaningful to user programs.

Related

Is there a way to directly translate C's "%02x" format to C++? [duplicate]

This question already has an answer here:
Inlining the UnrealEngine UE_LOG macro with C++
(1 answer)
Closed 9 months ago.
I am following a tutorial in which they use BIO_printf(bio_out,"%02x",bs->data[i] ); in order to get the characters of a serial number stored in bs->data (which is an array of unsigned char) and they use "%02x" to specify the format of the char. I am using c++ and I want to add each of these chars to a stringstream but I can't find a way to translate the format and instead of a serial number I get ጄ냾�㮚㭖嵺ﭔ촋ᙰ.
I have tried using
std::stringstream serial("Serial: ");
for (int i = 0; i < bs->length; i++)
{
serial << std::setw(2) << std::hex << bs->data[i] << std::endl;
}
but I still don't get a valid string, and
char* buffer = const_cast<char*>(serial.str().c_str());
sprintf(buffer, "%02x", bs->data[i]);
doesn't seem to work either (don't mind the const cast, I know it is bad practice)
You can use a combination of the std::setw(), std::setfill() and std::hex manipulators to set the width and fill characters. Also, you need to explicitly cast a char variable to an int in order to get the numerical representation, otherwise the << operator (on a char) will output (or attempt to output) the represented character.
Here's a short example using the std::cout stream (though the manipulators work in the same way on a std::stringstream object):
#include <iostream>
#include <iomanip>
int main()
{
char c = 13;
std::cout << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(c) << std::endl; // Shows 0d
return 0;
}

Why does this code give no output on online C++ compilers? [duplicate]

This question already has answers here:
String plus Char - what is happening?
(5 answers)
C++. Why std::cout << char + int prints int value?
(2 answers)
cout and String concatenation
(3 answers)
How object cout prints multiple arguments?
(4 answers)
Closed 10 months ago.
I was experimenting with a statement in C++ using online compilers. When I try to run this specific code
cout << num[i] + " " + num[i];
The online compilers give no output. I can change the + symbol to << but I want to know the reason that the code does not give any output on these online compilers.
Online compilers that I tried are onlinegdb, programiz, and jdoodle.
#include <iostream>
#include <string>
int main() {
std::string num = "123";
int i = 0;
std::cout << num[i] + " " + num[i];
return 0;
}
C++ is not like JavaScript or many higher-level languages, as in you may not delimit you data with +'s or ,'s. As shown in Lewis' answer, each item you wish to have printed must be separated by an insertion delimiter (<<). As for extracting, you may use the extraction delimiter (>>).
In your case, you are doing mathematical operations on the the characters themselves (adding together their numerical ASCII representations together, which could print unprintable and invisible characters). The printable ASCII characters range from 32 (space character) to 127 (delete character) (base 10). When summing '1' + ' ' + '1' you are left with (49 + 32 + 49) or (130) which exceeds the printable character range. Or you may also be accessing garbage as #pm100 said in the comments due to pointer arithmetic.
Here is an example of using the insertion operator:
#include <iostream>
int main(void) {
int some_int = 1;
std::cout << "this is my " << some_int << "st answer on StackOverflow :)"
<< std::endl;
return 0;
}
And as for the extraction operator:
#include <iostream>
int main(void) {
int num;
std::cout << "Enter an integer: ";
std::cin >> num; // stores the input into the `num` variable
std::cout << "The number is: " << num << std::endl;
return 0;
}
Pointer arithmetic:
const char* get_filename(const char* _path, size_t _offset) {
return (_path + _offset);
}
// This is an example
//
// path = "path/to/my/file/file.txt";
// offset ^ ^
// 0 |
// + 16 ------------|
// path = "file.txt";

Converting an int to a char array with a chosen format [duplicate]

This question already has answers here:
Integer to hex string in C++
(27 answers)
Closed 5 years ago.
I have an int which I want to convert to a char array, but I want the char array to be formatted in hexadecimal and with every byte of the int taking up exactly 2 char variables (filled out with zeroes).
To clarify what I mean, I have an example:
I want the int 232198 (0x38b06) to become "00038b06".
I can of course acomplish this by using this code:
#include <iostream>
#include <iomanip>
int main()
{
std::cout <<
std::hex <<
std::setw(8) <<
std::setfill('0') <<
232198 <<
std::endl;
return 0;
}
Which prints out:
00038b06
But that only prints it out to the console, and as I mentioned before, want to store it a char array.
I don't care if the code is portable or not, this just has to work for windows.
stringstreams are useful to do this:
std::stringstream sstr;
sstr <<
std::hex <<
std::setw(8) <<
std::setfill('0') <<
232198;
std::string str = sstr.str();
now str contains the formatted number. str.c_str() will give you a const char*.

How to print characters with spaces as a string in C++ [duplicate]

This question already has answers here:
std::cin input with spaces?
(8 answers)
Closed 8 years ago.
The code is not giving desired output
when I type in a string example "Ben Parker", the output is "Goodmorning, Ben" and not the entire name("Ben Parker") what seems to be the problem?
#include <iostream>
#include <stdlib.h>
#include <cstring>
int main() {
char your_name[20];
std::cout << "Enter your name: ";
std::cin >> your_name;
std::cout << "Goodmorning, ";
std::cout.write (your_name, strlen(your_name)) << std::endl;
return 0;
}
SOLUTION
This was a very old question when I just began programming.
The entire character array can be read and printed with a for loop, or better a string type variable can be used, since it is C++.
using string your_name; seems to fix the problem, which can be then printed with a simple std::cout << your_name << endl;
You probably put a space in between "Ben" and "Parker" in input. This would cause the cin logic to believe it had an answer after seeing the space following "Ben". You will probably want to read an entire line at a time to get past that problem. See this page for an example.

Can't output hex in C++ [duplicate]

This question already has answers here:
C++ cout hex format
(3 answers)
Closed 9 years ago.
I'm trying to output a hex value assigned to a variable x and I can't seem to get it working in C++. I can do it in standard C but am getting undesired results in C++.
#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, const char * argv[])
{
unsigned char x = 0xFF;
printf("%X\n", x);
cout << dec << x << endl;
cout << hex << x << endl;
return 0;
}
prints
FF
\377
\377
Because it's unsigned char, the stream thinks you want to output a character, rather than its value. Try casting to int
cout << hex << (int)x << endl;
You might also want to use setw(2) and setfill('0') stream modifiers to pad single-digit hex numbers to 2 digits (similar to using %02X with printf).