Apparently, on Linux (Centos 7, g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4)) you can seek to absurd offsets in files opened for reading. I can get the file length and check the offset myself, but shouldn't the seekg fail?
This program illustrates. No error conditions are detected, but the file is much less than 999999 bytes long.
#include <iostream>
#include <fstream>
int main(int argc, char **argv) {
std::ifstream f("./tstseek.cpp",std::ios::in);
if(!f.seekg(9999999)) {
std::cerr << "SEEK FAILED" << std::endl;
}
long int pos = f.tellg();
if(f.bad() || f.fail()) {
std::cerr << "SEEK FAILED" << std::endl;
}
if(f.eof()) {
std::cerr << "EOF AFTER SEEK" << std::endl;
}
std::string s;
std::getline(f,s);
if(f.bad() || f.fail()) {
std::cerr << "getline failed" << std::endl;
}
if(f.eof()) {
std::cerr << "EOF after getline" << std::endl;
}
std::streamsize bytesread = f.gcount();
std::cerr << "Position after seekg(9999999) = " << pos << std::endl
<< "bytes read = " << bytesread << std::endl
<< "string=[" << s << "]" << std::endl;
}
Related
I am writing a config for my program. This config is stored in json format using nlohman json. I am using std::fstream to write json object to file. All was fine, but after some moment my program stopped writing to file.
Here is a minimal reproducible example:
#include <iostream>
#include <nlohmann/json.hpp>
#include <fstream>
#include <iomanip>
bool load(std::fstream &config_fs) {
if (config_fs) {
try {
nlohmann::json json;
config_fs >> json;
std::cout << json << std::endl;
return true;
} catch (std::exception &e) {
std::cout << "54 " << (bool)config_fs << std::endl; // 1
std::cout << "Cannot load config: " << e.what() << std::endl;
return false;
}
}
std::cout << "Cannot load config because file is not open" << std::endl;
return false;
}
bool save(std::fstream &config_fs) {
std::cout << "37 " << (bool)config_fs << std::endl;
if (config_fs) {
nlohmann::json json{{"test", 42}};
std::cout << "39 " << (bool)config_fs << " " << config_fs.is_open() << " " << strerror(errno) << std::endl;
config_fs << std::setw(4) << json << std::endl;
std::cout << "41 " << (bool)config_fs << " " << config_fs.is_open() << " " << strerror(errno) << std::endl;
return true;
}
std::cout << "Cannot save config because file is not open" << std::endl;
return false;
}
int main() {
std::string config_file = "../config_test.json";
std::fstream config_fs(config_file, std::ios::in | std::ios::out);
if (!config_fs) {
std::cout << "Cannot open configuration file " << config_file << ", creating it" << std::endl;
config_fs.open(config_file, std::ios::out);
if (!config_fs) {
std::cout << "Cannot create config file " << config_file << std::endl;
} else {
config_fs.close();
config_fs.open(config_file, std::ios::in | std::ios::out);
}
}
if(!load(config_fs)) {
std::cout << "Cannot load config from " << config_file << ", putting default values" << std::endl;
std::cout << "21 " << (bool)config_fs << std::endl;
save(config_fs);
}
return 0;
}
And here is output of the programm:
54 1
Cannot load config: [json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal
Cannot load config from ../config_test.json, putting default values
21 1
37 1
39 1 1 Success
41 0 1 Success
It means that fstream closes after my write attempt with Success errno and file stays empty!
I do not know what may cause such a behavior. I also could not find any similar questions and i really confused about that.
Please point me, what can be reason for this problem.
Thank you!
UPD: Exception 'std::ios_base::failure[abi:cxx11]'
what(): basic_ios::clear: iostream error was thrown in output_stream_adapter::write_characters(const CharType* s, std::size_t length) after enabling exceptions for fstream with config_fs.exceptions(std::ios::badbit | std::ios::failbit);
Trying to get some data from CallNtPowerInformation(SystemPowerInfomation…) but the returned data doesn't seem to be correct (lidpresent should be true but it's false, VideoDimPresent should be false but it's true..) I'm new to C++ and I'm pretty sure I'm doing something wrong.
My code:
#include <NTstatus.h>
#define WIN32_NO_STATUS
#include <windows.h>
#include <Powrprof.h>
#include <iostream>
#pragma comment(lib, "Powrprof.lib")
int main()
{
SYSTEM_POWER_CAPABILITIES spwr;
NTSTATUS status = ::CallNtPowerInformation(SystemPowerInformation, NULL, 0, &spwr, sizeof(SYSTEM_POWER_CAPABILITIES));
if(STATUS_SUCCESS == status){
if(spwr.LidPresent){
std::cout << "LidPresent TRUE!" << std::endl;
}else{
std::cout << "LidPresent FALSE!" << std::endl;
}
if(spwr.VideoDimPresent){
std::cout << "VideoDimPresent TRUE!" << std::endl;
}else{
std::cout << "VideoDimPresent FALSE!" << std::endl;
}
if(spwr.SystemS1){
std::cout << "SystemS1 TRUE!" << std::endl;
}else{
std::cout << "SystemS1 FALSE!" << std::endl;
}
if(spwr.SystemS2){
std::cout << "SystemS2 TRUE!" << std::endl;
}else{
std::cout << "SystemS2 FALSE!" << std::endl;
}
if(spwr.SystemS3){
std::cout << "SystemS3 TRUE!" << std::endl;
}else{
std::cout << "SystemS3 FALSE!" << std::endl;
}
if(spwr.SystemS4){
std::cout << "SystemS4 TRUE!" << std::endl;
}else{
std::cout << "SystemS4 FALSE!" << std::endl;
}
}
else
{
std::cout << "CallNtPowerInformation failed. Status: " << status << std::endl;
}
return status;
}
You passed SystemPowerInformation, so lpOutputBuffer is expected to point to SYSTEM_POWER_INFORMATION structure.
You may want to pass SystemPowerCapabilities rather than SystemPowerInformation if you expect SYSTEM_POWER_CAPABILITIES.
See CallNtPowerInformation documentation.
I have these two poco programs, one sends the other receives. The receive doesn't crash, but I can't get the send to work. Sadly, the exception is not very helpful either, just saying "Net Exception". It might have to do with running both programs on the same machine, but still, the reuse address is set to true and so is the loopback.
//Receive
#include <string>
#include <iostream>
// MulticastSocket receive example
#include <Poco/Net/SocketAddress.h>
#include <Poco/Net/MulticastSocket.h>
using namespace std;
int main(int argc, char* argv[])
{
Poco::Net::initializeNetwork();
std::cout << "1" << std::endl << std::flush;
//Poco::Net::SocketAddress localAddr(Poco::Net::IPAddress(), 1900);
Poco::Net::SocketAddress localAddr("239.255.255.250", 1900);
std::cout << "2" << std::endl << std::flush;
Poco::Net::MulticastSocket socket(localAddr, true);
std::cout << "3" << std::endl << std::flush;
socket.setLoopback(true);
std::cout << "4" << std::endl << std::flush;
socket.setTimeToLive(4);
std::cout << "5" << std::endl << std::flush;
Poco::Net::SocketAddress groupAddr("239.255.255.250", 1900);
std::cout << "6" << std::endl << std::flush;
socket.joinGroup(groupAddr.host());
std::cout << "7" << std::endl << std::flush;
Poco::Net::SocketAddress sender;
char buffer[512];
int n = socket.receiveFrom(buffer, sizeof(buffer), sender);
std::cout << buffer << std::endl << std::flush;
Poco::Net::uninitializeNetwork();
return 0;
}
//Send
#include <string>
#include <iostream>
#include <Poco/Net/SocketAddress.h>
#include <Poco/Net/MulticastSocket.h>
#include <Poco/Net/NetException.h>
using namespace std;
using namespace Poco;
int main(int argc, char* argv[])
{
Poco::Net::initializeNetwork();
try
{
Poco::Net::SocketAddress address("239.255.255.250", 1900);
//Poco::Net::SocketAddress address(Poco::Net::IPAddress(), 1900);
std::cout << "1" << std::endl << std::flush;
Poco::Net::MulticastSocket socket(address, true);
std::cout << "2" << std::endl << std::flush;
socket.setLoopback(true);
std::cout << "3" << std::endl << std::flush;
//Poco::Net::SocketAddress sender;
char buffer[512];
buffer[0] = 'H';
buffer[1] = '\0';
std::cout << "Sending " << buffer << std::endl;
//socket.sendTo(buffer, 512, sender);
socket.sendBytes(buffer, 512, 0);
std::cout << "4" << std::endl << std::flush;
}
catch(const Poco::Net::NetException& ex)
{
std::cout << ex.what() << std::endl << std::flush;
}
Poco::Net::uninitializeNetwork();
return 0;
}
You have to bind to the IP of your computer and not the IP of the multicast group. You have commented the correct line out:
Poco::Net::SocketAddress localAddr(Poco::Net::IPAddress(), 1900);
Try looking at the MulticastEchoServer example that comes with Poco. It is under Net/testsuite/src/MulticastEchoServer.cpp in the sources.
void main() {
nodLista* LS=NULL;
FILE* F=fopen("asaceva.txt","r");
if(F!=NULL) {
char buffer[100]; int id;float pret;
fscanf(F,"d",&id);
while(!feof(F)) {
fscanf(F,"f",&pret);
fscanf(F,"s",buffer);
Produs* p= creareProdus(id,pret,buffer);
LS=inserareSfarsit(LS,*p);
fscanf(F,"%d",&id);
}
afisareLista(LS);
}
_getch();
}
afisareLista: displays the list
inserareSfarsit: inserts at the end
I don't understand why it doesn't get the data from the txt file. Can you explain why?
There are a couple of issues in your code:
main not returning integer.
not using fscanf consistently and correctly with placeholders.
you are not checking the return value of fscanf for failure.
NULL should be replaced with nullptr if you have C++11 support available.
The correct code should be like this:
int main() {
nodLista* LS=NULL;
FILE* F=fopen("asaceva.txt","r");
if(F!=NULL) {
char buffer[100]; int id;float pret;
if (!fscanf(F,"%d",&id))
cout << "Error happened: " << ferror(F) << ", error string: " << strerror(errno) << endl;
while(!feof(F)) {
if (!fscanf(F,"%f",&pret))
cout << "Error happened: " << ferror(F) << ", error string: " << strerror(errno) << endl;
if (!fscanf(F,"%s",buffer))
cout << "Error happened: " << ferror(F) << ", error string: " << strerror(errno) << endl;
Produs* p= creareProdus(id,pret,buffer);
LS=inserareSfarsit(LS,*p);
if (!fscanf(F,"%d",&id))
cout << "Error happened: " << ferror(F) << ", error string: " << strerror(errno) << endl;
}
afisareLista(LS);
}
_getch();
return 0;
}
I'm getting the following error:
./pcrecpp: symbol lookup error: ./pcrecpp: undefined symbol: _ZN7pcrecpp2RE6no_argE
when run my program on CentOS 5.4. But it works well on CentOS 6.2. The version of pcre is 8.31, and the version of pcre++ is 0.9.5. Below is the source code. Thanks for any guidance.
#include <iostream>
#include <pcrecpp.h>
int main(int argc, char ** argv)
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0] << " pattern text\n";
return 1;
}
pcrecpp::RE oPattern(argv[1]);
if (oPattern.FullMatch(argv[2]))
{
std::cout << argv[2] << " fully matches " << argv[1] << "\n";
}
else if (oPattern.PartialMatch(argv[2]))
{
std::cout << argv[2] << " partially matches " << argv[1] << "\n";
}
else
{
std::cout << argv[2] << " dose not match " << argv[1] << "\n";
}
}