LibXL load file failure - c++

Here is the code to load the xls/xlsx file:
int main()
{
BookHandle book = xlCreateBook();
if(book)
{
if(xlBookLoad(book, L"Slice.xlsx"))
{
SheetHandle sheet = xlBookGetSheet(book, 0);
if(sheet)
{
double d;
const wchar_t* s = xlSheetReadStr(sheet, 2, 1, 0);
if(s) wprintf(L"%s\n", s);
d = xlSheetReadNum(sheet, 3, 1, 0);
printf("%g\n", d);
}
}
xlBookRelease(book);
}
printf("\nPress any key to exit...");
_getch();
return 0;
}
These are actually the example code. the xlBookLoad() fails so that the if statement is skipped.
However, if I load its own file example1.xls, it succeeded.
Slice.xlsx and example.xls are in the same folder. I am 100% sure the file path is correct. It was the loading functionality that failed.
Now, I don't know why. Was that because the Slice.xlsx is kinda special? or LibXL is not the tool to load it? If so how can I read it?
I am attaching it here. Thanks a lot in advance to anyone that helps.
Slice.xlsx:
https://dl.dropboxusercontent.com/u/7949206/Slice.xlsx

From the documentation, it is stated that you should use xlCreateBook to work with a *.xls file and xlCreateXMLBook to work with a *.xlsx file. Thus, for Slice.xlsx, use xlCreateXMLBook in the place of xlCreateBook. http://www.libxl.com/documentation.html

Related

Overlap hundreds of histograms macro question

I have a directory trial which contains hundreds of histograms in it and a macro. Each is called in a way hists09876_blinded.root or hists12365_blinded.root. The order, however, is not like that. There are some missig histograms like hists10467_blinded.root hists10468_blinded.root hists10470_blinded.root. The ultimate goal is to get one histogram on a canvas which represents all of those combined together. The tricky thing is that each hists*****_blinded.root has around 15 1D histos in it, I need to pull out just one from each called sc*****.
I have 2 ideas, but I guess I should combine them together to get the final result.
First idea was to open histo by histo, but since there are some missed histos in the order, that does not work well.
void overlap()
{
TCanvas *time = new TCanvas("c1", "overlap", 0, 0, 800, 600);
const char* histoname = "sc";
const int NFiles = 256;
for (int fileNumber = 09675; fileNumber < NFiles; fileNumber++)
{
TFile* myFile = TFile::Open(Form("hists%i_blinded.root", fileNumber));
if (!myFile)
{
printf("Nope, no such file!\n");
return;
}
TH1* h1 = (TH1*)myFile->Get(histoname);
if (!h1)
{
printf("Nope, no such histogram!\n");
return;
}
h1->SetDirectory(gROOT);
h1->Draw("same");
myFile->Close();
}
}
After having read multiple posts on the pretty much the same question (1, 2, and this one) I have figured out what was wrong with my answer here: I did not know the file name may contain a zero if the number in its name is < 10000. Also, I failed to understand that the asterisks in the histogram name, which you refer to as sc*****, actually hide the same number as in the file name! I thought this was something completely different. So in that case I suggest you construct the file name and the histogram name you should be after in the same loop:
void overlap_v2()
{
TCanvas *time = new TCanvas("c1", "overlap", 0, 0, 800, 600);
const int firstNumber = 9675;
const int NFiles = 100000;
for (int fileNumber = firstNumber; fileNumber < firstNumber+NFiles; fileNumber++)
{
const char* filename = Form("trial/hists%05i_blinded.root", fileNumber);
TFile* myFile = TFile::Open(filename);
if (!myFile)
{
printf("Can not find a file named \"%s\"!\n", filename);
continue;
}
const char* histoname = Form("sc%05i", fileNumber);
TH1* h1 = (TH1*)myFile->Get(histoname);
if (!h1)
{
printf("Can not find a histogram named \"%s\" in the file named \"%s\"!\n", histoname, filename);
continue;
}
h1->SetDirectory(gROOT);
h1->Draw("same");
myFile->Close();
}
}
Since it is expected that some files are "missing", I suggest not to try to guess the names of the files that actually exist. Instead, use a function that lists all files in a given directory and from that list filter out those files that match the pattern of files you want to read. See for example these links for how to read the content of a directory in C++:
How can I get the list of files in a directory using C or C++?
http://www.martinbroadhurst.com/list-the-files-in-a-directory-in-c.html

PhysFS_init() returns non-zero with error: "no error"

Im experiencing a rather weird crash in my code and im unsure as to what causes it. Im trying to use PhysFS in my c++ code. the code below is part of a class and Visual Studio 2017 tells me that the crash appears in PHYSFS_mount() and subsequently in EnterCriticalSection(), which to my understanding has something to do with mutexes. Now from my understanding this should be correct (Note that the main calls initArchives() first)
physfs_initialized = false;
...
void scope::parse_archive(const std::string& archive_path, const std::string& path_in_archive)
{
assert(physfs_initialized);
m_archivePath = archive_path;
m_relativeArchivePath = path_in_archive.substr(1);
//fsx = std::filesystem or std::expiremental::filesystem whatever floats your boat
if(exists(fsx::path(archive_path))) return;
if(!PHYSFS_mount(m_archivePath.c_str(),"",0)) return;
const auto file = PHYSFS_openRead(m_relativeArchivePath.c_str());
if(file) m_isValid = true;
PHYSFS_close(file);
PHYSFS_unmount(m_archivePath.c_str());
}
...
void initArchives(char ** argv)
{
if (!PHYSFS_init(argv[0])) physfs_initialized = true;
//a bit of ugly syntax because of the need to consume the return type
atexit([]() {PHYSFS_deinit(); });
}
The crash apparently appears here
int __PHYSFS_platformGrabMutex(void *mutex)
{
EnterCriticalSection((LPCRITICAL_SECTION) mutex); // <-- here
return 1;
} /* __PHYSFS_platformGrabMutex */
Am I doing something wrong here ? Is this a problem of the library or even with my OS ? Was there something in the buildstep of PhysFS that I missed ?
Edit: I noticed that I read the return value of PHYSFS_init() wrong, however now I'm even more confused as PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()) returns "no error", what is going on here ?
Apparently there is a bug in PhysFS regarding Windows 10. That prohibits the correct execution of PHYSFS_init()
changing line 578 of phsyfs_platform_windows.c to
rc = pGetDir(accessToken, NULL, &psize);
and a recompile of the library fixed the problem for me :/
https://hg.icculus.org/icculus/physfs/rev/ece6769c0676
https://discourse.libsdl.org/t/resolved-physfs-exception-thrown/25697/11

allegro 5 writing files when using physfs

i am currently trying to figure out a way to write a file (an allegro configuration file to be exact) to a mounted zip-file using physfs and allegro 5.
reading the config file works fine, but when it comes to writing the changed config, nothing happens (e.g. the file is not re-written and thus remains in it's old state).
also, when not using physfs, everything works perfectly.
here's the code i use:
Game::Game(int height, int width, int newDifficulty)
{
PHYSFS_init(NULL);
if (!PHYSFS_addToSearchPath("Data.zip", 1)) {
// error handling
}
al_set_physfs_file_interface();
cfg = al_load_config_file("cfg.cfg");
if (cfg != NULL) // file exists, read from it
{
const char *score = al_get_config_value(cfg, "", "highScore");
highScore = atoi(score); // copy value
}
else // file does not exist, create it and init highScore to 0
{
cfg = al_create_config();
al_set_config_value(cfg, "", "highScore", "0");
highScore = 0;
al_save_config_file("cfg.cfg", cfg);
}
...
}
and in another function:
void Game::resetGame()
{
// high score
if (player->getScore() > highScore)
{
highScore = player->getScore();
// convert new highScore to char* that can be saved
stringstream strs;
strs << highScore;
string temp_str = strs.str();
char const* pchar = temp_str.c_str();
if (cfg != NULL) // file exists, read from it
{
al_set_config_value(cfg, "", "highScore", pchar);
al_save_config_file("cfg.cfg", cfg);
}
}
...
}
since the code works without physfs, i guess i handle the config file itself correctly.
any help would be highly appreciated!
cheers,
hannes
in the meantime, i solved the issue myself.
apparently, physfs has no ability to write to an archive.
therefore, i need to PHYSFS_setWriteDir("jhdsaf"), save the cfg-file in that folder and then replace the original zip-file by an updated version with the cfg-file, just before the game closes (after all resources are unloaded because the zip is otherwise still in use).
if anyone is interested in the code to do this, just reply to this post!
hannes

File.getFilename() in Arduino?

UPDATE:There's no getfilename(), but there's name() function!
I'm trying to make a simple program to store all filenames in a String array and then show them in the LCD.
Code:
String* list(File root, int len) {
if (!root.isDirectory()) return NULL;
String files[50];
int i = 0;
while (true) {
File f = root.openNextFile();
if (i < 50) files[i] = f.getFilename();
f.close();
i++;
}
len = i;
root.close();
return files;
}
Code to display in LCD:
void displayToLCD(String* files, int len) {
lcd.clear();
lcd.home();
lcd.print("Files on SD:");
for (int i = 0; i < len; i++) {
lcd.setCursor(0, 1);
lcd.print(files[i]);
delay(1000);
}
lcd.clear();
lcd.home();
}
But the problem is that the class File doesn't have the 'getFilename()' function. Is there any way to get the filename?
Please help.
Best regards,
Mateiaru
Just remembered that that on arduino.cc at File section, at openNextFile example, they use File.name()! So there's no getFilename().
Mateiaru
I would recommend that you look at my MP3 FilePlayer.ino example. It accomplishes what you are attempting, but just to the serial port.
Additionally it won't run out of memory, as it does not store the file names into an array or memory. Rather displays them and lets the user select the number. This can also be readily adapted to an up/down arrow menu, for an LCD.
Note that I am using SdFat. It has more functions and attributes that are not made public in standard SD. along with the file.getFilename() .

What value should i insert there?

i'm trying to set up a driver or something alike for my keyboard. I'm editing somebody elses code according to instructions but one thing is bothering me.
here's code
/* to add a new device, simply create a new DEVICE() in this list */
/* Fields are: "Name",VendorID,ProductID,Capabilities */
const libg15_devices_t g15_devices[] = {
DEVICE("Logitech G510",0x46d,0xc22d, G15_LCD|G15_KEYS|G15_DEVICE_5BYTE_RETURN|G15_DEVICE_IS_SHARED),
DEVICE("Logitech G15",0x46d,0xc222,G15_LCD|G15_KEYS),
DEVICE("Logitech G11",0x46d,0xc225,G15_KEYS),
DEVICE("Logitech Z-10",0x46d,0x0a07,G15_LCD|G15_KEYS|G15_DEVICE_IS_SHARED),
DEVICE("Logitech G15 v2",0x46d,0xc227,G15_LCD|G15_KEYS|G15_DEVICE_5BYTE_RETURN),
DEVICE("Logitech Gamepanel",0x46d,0xc251,G15_LCD|G15_KEYS|G15_DEVICE_IS_SHARED),
DEVICE(NULL,0,0,0)
};
/* return device capabilities */
int g15DeviceCapabilities() {
if(found_devicetype>-1)
return g15_devices[found_devicetype].caps;
else
return -1;
}
The first DEVICE entry is what i'm aiming for and a part of the code i added. here is where i stop.
int setLEDs(unsigned int leds)
{
int retval = 0;
unsigned char m_led_buf[4] = { 2, 4, 0, 0 };
unsigned char g510_led_buf[2] = {4, 0};
m_led_buf[2] = ~(unsigned char)leds;
if(g15DeviceCapabilities() & G15_DEVICE_G510) {
on G15_DEVICE_G510 it stops. i do not know what value i should be replacing it with.
Here's a pastebin of the entire code if this info is insufficient.
Pastebin Link
Thanks. :)
EDIT: I found out the functions are defined in another file. here they are.
Pastebin Link
So what i really need to do is define G15_DEVICE_G510 somehow in that file.
This is how it was supposed to be done.
#define G15_DEVICE_G510 32
#define G510_STANDARD_KEYBOARD_INTERFACE 0x0
then at a later point in the code
int setG510LEDColor(unsigned char r, unsigned char g, unsigned char b);
i managed to find a file with it from here
then i'd need to edit a line i had to this.
DEVICE("Logitech G510",0x46d,0xc22d, G15_LCD|G15_KEYS|G15_DEVICE_5BYTE_RETURN|G15_DEVICE_IS_SHARED|G15_DEVICE_G510),
the code for it was originally written by a guy who calls himself "multitude"
So thanks multitude :)