How to hide console cursor in c? - c

I have a simple C program that represents a loading screen within the console, but I can't get the cursor to hide. I tried cranking up the speed of the sleep function so that the cursor timer would be reset and the cursor would be gone but that doesn't work.
Any tips on how to hide the cursor?
Code:
#include <stdio.h>
#include <stdlib.h>
const int TIME = 1;
int main(int argc,char *argv[]){
int i;
while (1){
printf("loading");
for (i=0;i<3;i++){
sleep(TIME);
printf(".");
}
sleep(TIME);
printf("\r");
system("Cls");
sleep(TIME);
}
}

To extend on Bishal's answer:
To hide the cursor:
printf("\e[?25l");
To re-enable the cursor:
printf("\e[?25h");
Source

Add to your program the following function
#include <windows.h>
void hidecursor()
{
HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO info;
info.dwSize = 100;
info.bVisible = FALSE;
SetConsoleCursorInfo(consoleHandle, &info);
}
and call it in your main.
And read more in the MSDN

printf("\e[?25l");
This should work ! It is taken from ANSI codesheet where the characters are not just what they are seen. They act like some form of commands.

Here a solution that works both in Windows and Linux:
#include <iostream>
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <Windows.h>
#endif // _WIN32
using namespace std;
void show_console_cursor(const bool show) {
#if defined(_WIN32)
static const HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(handle, &cci);
cci.bVisible = show; // show/hide cursor
SetConsoleCursorInfo(handle, &cci);
#elif defined(__linux__)
cout << (show ? "\033[?25h" : "\033[?25l"); // show/hide cursor
#endif // Windows/Linux
}

Related

Why am I not receiving the events I am subscribed to?

I'm trying to listen to pointer motion events on an already created window (not by me), so first I got the window id using xwininfo and hardcoded it for testing, I tested it with different windows ids and for some windows it worked and for others it didn't.
alacritty window id: not working
mpv window id: working
Compile with: gcc pointermotion.c -o pointermotion -lxcb
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/xproto.h>
int
main(int argc, char **argv) {
xcb_connection_t *connection;
xcb_generic_event_t *ev;
xcb_motion_notify_event_t *mnev;
xcb_get_window_attributes_cookie_t cookie;
xcb_get_window_attributes_reply_t *reply;
xcb_window_t window;
connection = xcb_connect(NULL, NULL);
window = 0x3000002;
xcb_change_window_attributes(connection, window, XCB_CW_EVENT_MASK, (const uint32_t [1]) { XCB_EVENT_MASK_POINTER_MOTION });
xcb_flush(connection);
cookie = xcb_get_window_attributes_unchecked(connection, window);
reply = xcb_get_window_attributes_reply(connection, cookie, NULL);
assert(reply->your_event_mask == XCB_EVENT_MASK_POINTER_MOTION);
free(reply);
while (1) {
while ((ev = xcb_poll_for_event(connection))) {
switch (ev->response_type & ~0x80) {
case XCB_MOTION_NOTIFY:
mnev = (xcb_motion_notify_event_t *)(ev);
printf("%d, %d\n", mnev->event_x, mnev->event_y);
break;
default:
break;
}
free(ev);
}
}
return 0;
}

Address boundary error when invoke swapcontext()

I've written a simple program, use ucontext library. However, a signal SIGSEGV (address boundary error) occurred. The running env is MacOS. I do not know what's wrong I made?
Updated Here: Version 2
As #Jeremy suggest, we could use static on main_context and work_context. However, if we change work_context to an array, it still failed
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/time.h>
#include <unistd.h>
#define _XOPEN_SOURCE 600
#include "ucontext.h"
static ucontext_t main_context;
static ucontext_t work_context[3]; // version 2: from ucontext_t to an array
static void counter()
{
for (int c = 0; ; c++) {
fprintf(stderr, "c = %d\n", c);
sleep(5); // avoid busy loop
}
}
static ucontext_t* make_context1(ucontext_t *ucp, void (*func)())
{
getcontext(ucp);
sigemptyset(&ucp->uc_sigmask);
void *sp = malloc(SIGSTKSZ);
if (sp == NULL) {
fprintf(stderr, "malloc failed\n");
exit(-1);
}
ucp->uc_stack = (stack_t) { .ss_sp = sp, .ss_size = SIGSTKSZ, .ss_flags = 0 };
ucp->uc_link = &main_context;
makecontext(ucp, func, 0);
return ucp;
}
int main() {
printf("start\n");
make_context1(work_context, counter);
make_context1(work_context+1, counter); // added in version 2
make_context1(work_context+2, counter); // added in version 2
swapcontext(&main_context, work_context);
printf("main exit\n");
return 0;
}
For some reason the code runs without crashing if I change these two lines:
ucontext_t main_context;
ucontext_t work_context;
to this:
static ucontext_t main_context;
static ucontext_t work_context;
I'm sure there is a good explanation for this, but I don't know what it is :(
Well, that's simple - SIGSTKSZ is too small of a stack for printf. Increase it. Quadruple it.
Move #define _XOPEN_SOURCE 600 on top of the file. See man feature_test_macros.
Add #include <signal.h> for sigemptyset. Change "ucontext.h" into <ucontext.h>- it's a standard header.

Use Windows API Callback to retrieve Network Adapter Status

I use the lines of code below (not that important for my question) to retrieve the current status of the existing network adapters. See the comment marked "HERE".
This works fine and it prints this text:
But I like to use a Callback or similar in C instead of my current code. I like to know if there is a way Windows 7 can alarm me, if the OperationStatus of one of my network adapters has changed? My problem is I dont know how to start.
#include <stdafx.h>
#include <winsock2.h>
#include <iptypes.h>
#include <iphlpapi.h>
#include <windows.h>
#include <iostream>
const ULONG MAX_BUFFER_SIZE = 15000;
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
int _tmain(int argc, _TCHAR* argv[])
{
PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL;
ULONG bufferSize = MAX_BUFFER_SIZE;
pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(bufferSize);
GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddresses, & bufferSize);
do{
std::wcout<<"Name:\t\t\t "<<pAdapterAddresses->Description<<std::endl;
std::cout<<"OperationStatus:\t "<<pAdapterAddresses->OperStatus<<std::endl;
//HERE: prints network adapter status
if(pAdapterAddresses->Next != 0){
pAdapterAddresses = pAdapterAddresses->Next;
std::cout<<"\n";}
} while(pAdapterAddresses->Next != 0);
std::cin.get();
return 0;
}

OpenCV multithreading XInitThreads error

I am an embedded programmer and using a multithreaded application which is going to receive pixel data over serial line and display it in a window. I am using openCV's cvSetData() method to copy the data received over serial line and populate it to an openCV array. Also using the cvShowImage() function I am displaying the continuously updating pixel data( concept of displaying a video).
Here is a snippet from my code:
//-------------------------------------Start of code------------------------------------//
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include "serial_comm_defines.h"
#include <opencv2/highgui/highgui.hpp>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <pthread.h>
extern unsigned char array[COUNT_LIM];
IplImage *newimage;
img_disp_method(void)
{
cvSetData((CvArr*)newimage, (void*)array, 1556);
cvNamedWindow("Mywindow",CV_WINDOW_FREERATIO);
cvResizeWindow("Mywindow", 1556, 360);
cvShowImage("Mywindow",(CvArr*)newimage);
cvWaitKey(1);
}
void *serial_thread_method(void* my_fd)
{
clock_t start = 0, end = 0;
double time_taken = 0;
if ((int)my_fd<0)
printf("\nError opening device file\n");
else
{
printf("\nDevice file opened successfully\n");
if ( serial_config((int)my_fd) < 0)
printf("\nUnable to configure serial port\n");
else
{
printf("\nSerial port configured successfully\n");
for(;;)
{
start = clock();
serial_read((int)my_fd);
end = clock();
printf("\nTime taken:%f seconds\n", (double)((end-start)/CLOCKS_PER_SEC));
}
}
}
close ((int)my_fd);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t serial_read_thread;
int my_fd=0, i=0, temp=0, serial_thread_ret=0;
newimage = cvCreateImageHeader(cvSize(HEIGHT, WIDTH), IPL_DEPTH_8U, 0x01);
struct timeval my_value={0,10000};
struct timeval my_interval={0,10000};
struct itimerval my_timer={my_interval,my_value};
setitimer(ITIMER_REAL, &my_timer, 0);
signal(SIGALRM, img_disp_method);
my_fd = open_device_file((char**)argv);
if ( (serial_thread_ret = pthread_create(&serial_read_thread, NULL, serial_thread_method, (void*)my_fd) == 0))
fprintf(stdout, "\nSerial read thread created successfully\n");
else
perror("\nError creating serial read thread\n");
pthread_join(&serial_read_thread, NULL);
cvReleaseImageHeader(&newimage);
return NULL;
}
//----------------------------------------End of code--------------------------------------//
The code is compiling fine. But when I execute the binary it throws the following error. I also observed that if change the value of timer (value of my_value and my_interval) to anywhere greater than 30ms (30000) the code works just fine. Please explain what is happening.
Try using a virtual timer instead of a real timer.
Something like this
setitimer(SIGVTALRM, &my_timer, 0);
signal(SIGVTALRM, img_disp_method);

breaking out of a double after an elapsed time in C

I have a question I am writing a code that find the perfect number by brute forcing the algorithm which is required by my assignment. I want to see how far the ranges goes in 15 seconds. I tried using a while loop and an alarm but it seems to not work at all. How would I go from there?
Thanks
Heres my code:
#define _POSIX_SOURCE
#define _BSD_SOURCE
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
volatile int stop=0;
void sigalrm_handler( int sig ){
stop = 1;
}
int main(int argc, char **argv){
struct sigaction sact;
int num_sent = 0;
sigemptyset(&sact.sa_mask);
sact.sa_flags = 0;
sact.sa_handler = sigalrm_handler;
sigaction(SIGALRM, &sact, NULL);
alarm(15); /* Request SIGALRM in 60 seconds */
while (!stop) {
for (;;){
for (;;){
}
}
}
printf("%d \n", num_sent);
exit(0);
}
Even if the alarm gets triggered and set stop to a non-zero value you won't notice since your for loop doesn't return to the outer while. You need to apply the condition to all loops that should be stopped:
while (!stop) {
for (;!stop;){
for (;!stop;){
}
}
}
An alternative to alarm is simply checking whether you crossed a certain timepoint:
time_t end = time(0) + 15;
while (end < time(0)) {
for (;end < time(0);){
for (;end < time(0);){
}
}
}

Resources