as a school project I have to code a video game with SDL2, imgui and SFML and I'm facing a really weird problem :
getline seems unreliable on macOS but not on linux
Let me explain, when I compile and run my code, I am able to read my configuration file properly and display the data on screen : it is working everytime on my linux computer but on my macbook it is working like 1 time out of 5.
My configuration file :configuration file
how the information is supposed to be displayed (working properly on linux but not everytime on macOS) : how it is when it works
The code :
// Récupération des derniers paramètres
std::ifstream fichierSauvegardeR ("data/save.txt");
if (fichierSauvegardeR.is_open())
{
getline(fichierSauvegardeR, strNbDes);
strcpy(buf_nb_des, strNbDes.c_str());
getline(fichierSauvegardeR, strNbJoueurs);
strcpy(buf_nb_joueurs, strNbJoueurs.c_str());
// getline(fichierSauvegardeR, strNomJoueur);
// strcpy(noms_joueurs[0], strNomJoueur.c_str());
for (int i = 0; i < nbJoueurs; i++) {
if(!getline(fichierSauvegardeR, strNomJoueur))
{
break;
}
else
{
strcpy(noms_joueurs[i], strNomJoueur.c_str());
}
}
fichierSauvegardeR.close();
}
Note that, the first 2 lines of the configuration file are always properly read (even on macOS), what doesn't work is the other lines (I've tried replacing the "\n" by std::endl and it didn't changed anything)
Without responding to your answer (i don't have a mac for testing). I see that you use many C features. I recommend you to use "istringstream" to parse your file.
Something like this: https://stackoverflow.com/a/9551101/12374897
Related
I have an app that generates a dependencies.dot file which I then want to convert to an SVG image.
When I do that from a simple application like so:
int main(int argc, char * argv[])
{
system("dot -Tsvg ../BUILD/dependencies.dot > ../BUILD/dependencies.svg");
return 0;
}
It works great. The SVG image is present and working.
When I instead run it from my Qt application, the SVG file is created (by the shell), but it remains empty.
Any idea what could prevent dot from outputting data to its stdout?
Just in case, I also tried a cat to send the input through stdin instead of a filename:
system("cat ../BUILD/dependencies.dot | dot -Tsvg > ../BUILD/dependencies.svg");
And that didn't make any differences.
Also using the full path (/usr/bin/dot) did not help either.
Another test, I tried to use popen() and the first fread() immediately returns 0 (i.e. the mark of EOF).
It may not be Qt, but something is interacting with dot's ability to do anything. Any pointers on why that is would be wonderful.
Maybe an important note? I start my app. from a console, so stdin, stdout and stderr should all work as expected. I actually can see debug logs appearing there and other apps seem to work just as expected (i.e. My Qt app. can successfully run make, for example).
Here is an example of the resulting SVG (when I don't run it from within my Qt app):
For reference, the source code can be found on github. This is part of the snapbuilder. A tool that I use to run a build on launchpad. It's still incomplete, but it's getting there.
https://github.com/m2osw/snapcpp/tree/master/snapbuilder
The specific function to look for: project::generate_svg().
I still have no clue what side effect Qt has on system() that the dot command would fail. However, if using my own fork() + execve(), then it works.
I wanted a new process class for my environment, so I implemented that. This newer version is using FIFOs or directly opening closing files that it passes to the process.
...
// write the script in `std::stringstream dot` then:
//
std::string script(dot.str());
g_dot_process = std::make_shared<cppprocess::process>("dependencies");
g_dot_process->set_command("/usr/bin/dot");
g_dot_process->add_argument("-Tsvg");
g_dot_process->add_input(cppprocess::buffer_t(script.data(),
script.data() + script.length()));
g_dot_process->set_capture_output();
g_dot_process->set_output_capture_done(output_captured);
g_dot_process->start(); // TODO: check return value for errors
...
// and in output_captured()
//
void snap_builder::svg_ready(std::string const & svg)
{
std::string const svg_filename(...);
{
std::ofstream out;
out.open(svg_filename);
if(!out.is_open())
{
std::cerr << "error: \n";
return;
}
out.write(svg.c_str(), svg.size());
}
dependency_tree->load(QString::fromUtf8(svg_filename.c_str()));
}
Now the dot file is generated and displayed as expected.
This is rather strange since most everything else I've done with a simple system() call works as expected. There must be something about stdin or stdout that makes dot not do its work.
all
I'm pretty new to programming and I'm currently teaching myself C++ with sublime text editor. I'm having a problem where the code does not proceed after I input something through cin. For example,
#include <iostream>
using namespace std;
int main() {
string password = "password";
cout << "Enter your password: " << flush;
string input;
cin >> input;
if(input == password) {
cout << "Password accepted." << endl;
} else {
cout << "Access denied." << endl;
}
return 0;
}
After I put my input, it doesn't cout anything such as "password accepted" or "access denied". Does anyone know how to solve this problem and make it work? Thanks.
As mentioned your code does work as expected.
The issue is when you build a c++ program in sublime text it will compile that file and then run. What you see is sublime text piping the output from your program back to a window within sublime text.
Sublime does not have the ability to send input back to your program. Hence why your program "does not proceed after I input something through cin". There are some plugins available on the linux version of sublime that give access to a full terminal emulator, I have not tried using one of these but they do exist.
What I would recommend is that you learn how to use the gnu tool chain using the command line.
This is an old post but since I faced the same problem and this was the first page to pop up when I searched for it, I'll post the solution I think best for other newbros (Does this term work outside of Eve online? Who knows...).
Do remember I am new as well and what I am saying is probably the wrong approach and bad for you, but it will get you started....
Option 1: Use Sublime text to edit and run the file on terminal as everyone suggests. After the first few times it gets extremely repetitive and annoying. As long as you know how to do it, you should be fine. NOT RECOMMENDED.
Option 2: Use VS Code or other IDEs. The problem with this one is that sublime text is just faster to start which is primarily why I like subl. In all honesty VS code is also fast and responsive and I think switching to it is not at all a bad idea.
Option 3: If you still wanna continue using Sublime text. Set it up for something they call competitive programming. Skip the 'bits/stdc++.h' part and do everything else. Follow this link: https://www.geeksforgeeks.org/setting-up-sublime-text-for-cpp-competitive-programming-environment/
In the rare event this webpage stops existing in the future:
Step 1: Have mingw/mingw64 compiler installed and added to path. (You will find plenty of resources that will help you with that).
Step 2:
(i) Open Sublime Text editor and then go to Tools > Build System > New Build System.
(ii) Paste the following code in the file and save it.
{
"cmd": ["g++.exe", "-std=c++17", "${file}",
"-o", "${file_base_name}.exe",
"&&", "${file_base_name}.exe<inputf.in>outputf.out"],
"shell":true,
"working_dir":"$file_path",
"selector":"source.cpp"
}
(iii) Name the file as “CP.sublime-build“ (or anything really, just name something you know so that you can find it from the Tools > Build system list. Also make sure to keep the '.sublime-build' part.)
Step 3: Create these three new files and save them in the same folder. (Keep it somewhere where you store your codes or something like that).
file.cpp: The file for writing the code.
inputf.in: The file where we will be giving the input.
outputf.out: The file where the output will be displayed.
//Also don't change the names of these files since this is part of the code we had earlier.
Step 4: Setting up Window layout:
-Select View > Layout > Columns : 3. This will create three columns in the workspace. Move the three files into three columns.
-Select View > Groups > Max Columns : 2.
-Select the build system we just created from Tools > Build System > CP (or whatever you named it).
This will create a live environment for you write and run/test code at the same time in subl. o7
One way to do this in Submlime is to create a new Build System.
Goto Tools > Build System > New Build System..
Paste something like below into the open file and save it.
{
"cmd": ["bash", "-c", "/usr/bin/g++ '${file}' -o '${file_path}/${file_base_name}' && open -a Terminal.app '${file_path}/${file_base_name}'"]
}
*This is for Mac OSX, you will have the change it for your environment.
Change Build System to saved name
When you build next time, there will be a new Terminal App window waiting for the cin input.
I'm new the Ubuntu enviornment and I've also never used eclipse before.
So I'm trying to do a very simple task of just opening a file to read. I developed this on my mac in xcode and it works but when I put it through eclipse it fails.
I am calling this function continuously in order to simulate a state change like if someone pressed a button. The code is:
int event = 0;
ifstream inFile;
inFile.open("StatusFiles/currentEvent.txt"); //Crashes here after a couple times
if(inFile)
{
inFile >> event;
inFile.close();
}
else
{
cout << "StatusFiles/currentEvent.txt Not Found" << endl;
}
Very simple and the code is very common in order to open files in C++. There isn't a permission issues and I've included all the libraries I needed and I have the correct path.
I can read from the file a few times, but after two or three reads when i call this function, the code fails
The line it fails on line #2 is when I try to open the file. Eclipse yells at me saying:
No source available for "std::basic_ifstream>::open() at 0xb8f83982
This literally makes no sense to me and I would very much like some help!
--
Thanks
This is driving me up the wall..
I've got a very simple SDL2 program.
It has a array of 3 SDL_Texture pointers.
These textures are filled as follows:
SDL_Texture *myarray[15];
SDL_Surface *surface;
for(int i=0;i<3;i++)
{
char filename[] = "X.bmp";
filename[0] = i + '0';
surface = SDL_LoadBMP(filename);
myarray[i] = SDL_CreateTextureFromSurface(myrenderer,surface);
SDL_FreeSurface(surface);
}
This works, no errors.
In the main loop (which is just a standard event loop waiting for SDL_QUIT, keystrokes and a user-event which a SDL_Timer puts in the event queue every second) I just do (for the timer triggered event):
idx = (idx+1) % 3; // idx is global var initially 0.
SDL_RenderClear(myrenderer);
SDL_RenderCopy(myrenderer, myarray[idx], NULL, NULL);
SDL_RendererPresent(myrenderer);
This works fine for 0.bmp and 1.bmp, but the 3rd image (2.bmp) simply shows as a black field.
This is structural.
If I alternate the first 2 images they are both fine.
If I alternate the 2nd and 3rd image the 3rd image doesn't show.
If I use more than 3 images then 3 and upwards show as black.
Loading order doesn't matter. It starts going wrong with the 3rd image loaded from disk.
All images are properly formatted BMP's.
I even saved 2.bmp back to disk under a different name by using SDL_SaveBMP() after it was loaded to make sure it got loaded in memory OK. The new file is bit for bit identical to the original.
This program, without modifications and the same bmp files, works fine on OSX (XCode5) and Windows (VC++ 2012 Express).
The problem only shows on the Raspberry PI.
I have placed explicit error checks on every call that can leave a result/error-code (not shown in the samples above for brevity) but all of them show "no error".
I have used the latest stable source set of www.libsdl.org and compiled as instructed (configure, make, make install, etc.).
Anybody got any idea what could be going on ?
P.S.
Keyboard input doesn't seem to work either on my PI, but I haven't delved into that yet.
Answering myself as I finally figured it out myself...
I finally went back to the README-raspberrypi.txt that came with the SDL2 sources.
I didn't read it carefully enough the first time around...
Problem 1: I'am running on a FULL-HD display. The PI's default GPU memory is 64MB which is not enough for large displays and double-buffering. As suggested in the README I increased this to 128MB and this solved the black image problem.
Problem 2: Text input wasn't working because my user-account was not in the input group. I had added the default "pi" account to the input group initially, but when I later started using another account I forgot to add that user to the group.
In short: Caught by my own (too) quick skimming of the documentation.
wont load my picture
my default error message which is"error loading picture.bmp" pops up every time and wont run
#include "allegro.h"
int main(void)
{
char*filename="picture.bmp";
BITMAP*image;
int ret;
allegro_init();
install_keyboard();
set_color_depth(32);
ret=set_gfx_mode(GFX_AUTODETECT_WINDOWED,640,480,0,0);
if(ret!=0)
{
allegro_message(allegro_error);
return 1;
}
image=load_bitmap(filename,NULL);
if(!image)
{
allegro_message("error loading %s",filename);
return 1;
}
blit(image,screen,0,0,0,0,SCREEN_W,SCREEN_H);
destroy_bitmap(image);
textprintf_ex(screen,font,0,0,1,-1,"%dx%d",SCREEN_W,SCREEN_H);
while(!keypressed());
allegro_exit();
return 0;
}
END_OF_MAIN()
You're going to need to provide some more information...
What platform are you using? (MS Visual C++? Linux? Mac?...)
Which version of Allegro? (I'm guessing 4.x)
Assuming your question is, "How do I get my Allegro program to display my bitmap as intended," try to
Make sure the resulting executable file and picture.bmp are in the same directory. My guess is you are using some type of Microsoft IDE on Windows and you are trying to run the program from within the IDE (like via the debug menu or pressing F5) The resulting executable is put in a special output directory. It can't find your picture.bmp file.
Alternatively, you can try providing the full path to your picture.bmp file. You should only use this method to see if this is indeed the problem, though.
I believe your program might not be able to locate the bitmap image you are attempting to load. Try inserting the exact path to your bitmap in your code.
For example:
char*filename="C:\My Documents\Pictures\picture.bmp";