|
Could somebody please explain to me why I do not see the "perror" in expected code sequence?
Thanks
int main() {
cout << "Basic bluetooth app BLUEZ_LINUX " << endl; inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags;
int i;
char addr[19] = { 0 };
char name[248] = { 0 };
dev_id = hci_get_route(NULL);
SHOULD PRINT PERROR HERE ??
if (dev_id < 0) {
perror("Error: Bluetooth device not found"); }
#ifdef DEBUG
cout << " dev_id = hci_get_route(NULL) " << endl; cout << " dev_id " << hex << +dev_id << endl; #endif
#ifdef BYPASS // replaced with abpve perror
dev_id = hci_get_route(NULL);
#endif
sock = hci_open_dev(dev_id);
#ifdef DEBUG
cout << " sock = hci_open_dev( dev_id ) " << endl; cout << " sock " << hex << +sock << endl; #endif
if (dev_id < 0 || sock < 0) {
perror("Error: Opening socket");
}
#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl; cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endif
len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl; cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endif
ii = (inquiry_info*) malloc(max_rsp * sizeof(inquiry_info));
#ifdef BYPASS
if (ii)
perror("Error: inquiry_info*");
if (ii)
perror("Error: inquiry_info*");
#endif
#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl;
cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endif
#ifdef DEBUG
cout << " max_rsp " << hex << +max_rsp << endl;
cout << " num_rsp " << hex << +num_rsp << endl;
cout << " len " << hex << +len << endl;
cout << " flags " << hex << +flags << endl;
#endif
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
if (num_rsp < 0)
perror("Error: hci_inquiry");
#ifdef BYPASS
if (num_rsp < 0)
perror(NULL);
#endif
#ifdef DEBUG
cout << " num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags); "
<< endl; cout << " num_rsp " << hex << +num_rsp << endl; #endif
if (num_rsp < 0)
perror("Error: hci_inquiry");
#ifdef DEBUG
cout << " HERE @line " << dec << __LINE__ << endl; cout << " TRACE file " << __FILE__ << endl;
cout << " function " << __FUNCTION__ << endl;
#endif
for (i = 0; i < num_rsp; i++) {
ba2str(&(ii + i)->bdaddr, addr);
memset(name, 0, sizeof(name));
if (hci_read_remote_name(sock, &(ii + i)->bdaddr, sizeof(name), name, 0)
< 0)
strcpy(name, "[unknown]");
printf("%s %s\n", addr, name);
}
#ifdef BYPASS
free( ii );
close( sock );
#endif
return 0;
}
Basic bluetooth app BLUEZ_LINUX
dev_id = hci_get_route(NULL)
dev_id ffffffff
sock = hci_open_dev( dev_id )
sock ffffffff
HERE @line 84
TRACE file ../src/BLUE.cpp
function main
HERE @line 94
TRACE file ../src/BLUE.cpp
function main
HERE @line 109
TRACE file ../src/BLUE.cpp
function main
max_rsp ff
num_rsp 0
len 8
flags 1
num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
num_rsp ffffffff
HERE @line 154
TRACE file ../src/BLUE.cpp
function main
Error: Bluetooth device not found: No such device
Error: Opening socket: No such device
Error: hci_inquiry: No such device
Error: hci_inquiry: No such device
|
|
|
|
|
It does print the message at the bottom as you can see in the above output. Most likely because the stderr stream is not displayed until the application terminates
|
|
|
|
|
Richard MacCutchan wrote: Most likely because the stderr stream is not displayed until the application terminates
I think that's because C++ IO streams and C stdio streams are no synchronized. Try using stdi::ios_base::sync_with_sdio . std::ios_base::sync_with_stdio - cppreference.com
|
|
|
|
|
Not according to my tests, and ultimately cout (under the covers) will be printing to stdio/stderr in normal fashion.
|
|
|
|
|
Hmm.. I've compiled the OP's code and my own test code (below) and both times I get perror() and cout code interleaved. Not sure what I might be doing differently than the you guys. I've tried on both Fedora 29 (g++ v 8.3.1) and rpi (g++ v 6.3.0). Now I'm confused ...
$ cat errtest.cpp
#include <iostream>
#include <cerrno>
using namespace std;
int main()
{
for(errno= 0; errno < 4; ++errno) {
cout << "errno = " << errno << endl;
perror("Error");
}
}
$ make errtest
g++ -Wall -Wextra -std=c++17 -O2 errtest.cpp -o errtest
$ ./errtest
errno = 0
Error: Success
errno = 1
Error: Operation not permitted
errno = 2
Error: No such file or directory
errno = 3
Error: No such process
|
|
|
|
|
Sorry, my previous comment was unclear (or incorrect). I do get stdout and stderr correctly interleaved. I have a feeling that OP is using some weird stuff (cf Bluez questions).
Interesting how your sample code matches mine quite closely.
|
|
|
|
|
Only thing I can think of ATM is that the OP is running the code inside whatever terminal his IDE provides, and that's doing something odd with termio settings. I've tried messing with setvbuf() and various stty options, but always get interleaved output.
That being said, it should be pointed out to the OP that stdout (cout) and stderr (cerr), are different output streams. If you take my code and remove the << endl from line 9, then the output is quite different!
|
|
|
|
|
Really for the OP but I will put here to follow the discussion
Someone is on a multicore processor and the streams which are buffering are on different cores with resource locks
This is generally not guaranteed to give the expected order
printf("Expect 1\n");
perror("Expect 2\n");
printf("Expect 3\n");
Simply put two independent streams are not guaranteed to synchronize without you forcing the issue.
In the above Expect1 will always be before Expect3 but Expect2 can be before, in the middle or after those two lines.
sync_with_stdio() if implemented will work but it implies a heavy overhead on a many multicore situation which is why it might be off. I think it is supposed to default on with some c++ versions (but on multicore it is often violated because it is horrific) you would need to check with your compiler.
The simple answer is stop using perror and simply just use one stream aka printf/cout, flush after each print or put lock primitives in the order to guarantee the order.
It is easily avoidable ... so avoid it
In vino veritas
modified 12-Mar-19 1:36am.
|
|
|
|
|
#include <stdio.h>
#include<conio.h>
#include<string.h>
struct students {
char name[20];
int age;
};
void main(){
struct students firstyear_bex[5];
for(int i=0;i<5;i++){
puts("Enter your name:");
gets(firstyear_bex[i].name);
puts("\n");
puts("Enter your age:");
scanf("%d",&firstyear_bex[i].age);
}
puts("\n");
for(int i=0;i<5;i++){
puts(firstyear_bex[i].name);
puts("\t");
printf("%d",firstyear_bex[i].age);
puts("\n");
}
}
i am a real begineer and i wanted to ask for the name and the details and display it like it is. but when i run it, the outputs are a bit funny, i dont get the proper order of printouts and when i enter something more it does nothing, but if i keep on entering it will take it but show all of it at the end with not the proper order. please help.
.
i use mingw gcc compiler
modified 10-Mar-19 9:42am.
|
|
|
|
|
Evolt_Pratom wrote: the outputs are a bit funny What does that actually mean? Please explain exactly what inputs you enter and what results you see; we cannot guess.
OK, I see the problem. You are using scanf to read the age, which leaves a carriage return character in the input buffer. So your next call to gets will read that as an empty string and continue on to request the age. Add a call to gets(xxx) after the scanf call, where xxx is a dummy buffer, e.g. char xxx[5]; .
|
|
|
|
|
Richard MacCutchan wrote: Add a call to gets(xxx) after the scanf call, where xxx is a dummy buffer, e.g. char xxx[5]; . I think adding a carriage return to the end of the scanf format string will also work, will it not?
|
|
|
|
|
I tried that myself and it did not. It's about time scanf was consigned to the trash where it belongs.
|
|
|
|
|
i dont know what happened but i used scanf instead of gets and it worked. Love to know how it happened tho.
modified 10-Mar-19 10:55am.
|
|
|
|
|
I explained how in my earlier message.
|
|
|
|
|
Learning programmer need some help. I understand c++ Classes and I used to think I understood namespaces. But while trying to learn templates I'm getting kinda confused what is going on with this template example.
template <typename CharT, typename Traits, typename Alloc>
const CharT* std::basic_string< CharT, Traits, Alloc >::c_str() const [inline]
//and later the definition of the member function c_str()
const _CharT* c_str() const { return _M_data(); }
(a) Do you call the first line the template declaration?
(b) Do you call the second line the template implementation or definition?
(c) It appears to be a scope resolution :: to the member function c_str() but what is the [inline] bracket syntax?
(d)Also I assume the < CharT, Traits, Alloc > are defined in the header (elsewhere) with some value (overloaded or not)?
Just anywhere you can illuminate what I'm missing on the concept.
|
|
|
|
|
I still haven't understood the [INLINE] square brackets thing (yet) but I've begun to understand the templates concept amongst all the syntax MUCH better when I found this Article here on Code Project.
An Idiots Guide to C++ Templates-Part-1
So I guess I'm an idiot since that page helped me more than any I've read previous. A happy idiot now.
|
|
|
|
|
If it's any consolation I have been writing (sort of) C++ code for more than 20 years and still struggle with templates and lambdas.
|
|
|
|
|
Totally agree!
And I still avoid using lambdas as well.
|
|
|
|
|
Thanks Richard and Victor for the consolations. This is a much nicer forum than some. I do try to research before posting but sometimes without help I get stumped.
|
|
|
|
|
Rw237 wrote: (c) It appears to be a scope resolution :: to the member function c_str() but what is the [inline] bracket syntax?
Where did you get this template example from? The only place I've found the [inline] syntax is here (gcc 4.6.3 api docs). That syntax does not show up in the current API docs, nor does it show up in the libstdc++ sources for gcc 4.6.3 or gcc 8.2. It is also not described in the the MS c++ template docs or the template docs at cpprefereence.com. I'm thinking that's a documentation note that c_str() may be declared as an inline function, much the same as the man page for a utility might show optional parameters e.g. find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]
modified 8-Mar-19 13:02pm.
|
|
|
|
|
Thanks k5054, that must be it. Probably only novice learning dummies like me fail to ascertain that. You have cleared up my confusion and I can stop searching for this new mysterious syntax that I've never seen before.
|
|
|
|
|
I managed to get MDI tear off functionality into my app, like VS does. I placed the teared off view window to a dockable pane.
Now I would like to get the Aero Snap (Dragging caption with mouse to monitor top, corners, etc.) functionality for the teared off window.
Someone out there to get me into the right direction?
Regards,
Franz
|
|
|
|
|
This behaviour is MFC native .. your app is a MFC/MDI app ?
|
|
|
|
|
My app is MFC, yes. Found out that snap functionality works only with CFrameWnd inherited windows and not with CDockablePane, as they do not have a DWM caption bar.
|
|
|
|
|
We have a C++ MFC MDI application with a very heavy computational part.
And we want to run it on HPC cluster. Do we need to rewrite the application some specific way to do it? If yes, then what needs to be changed. What the simplest Windows cluster could look like and configured? How to deploy the app and distribute the job?
Thanks.
modified 7-Mar-19 10:16am.
|
|
|
|