Center text in console with windows api? - c

Is there a way to use windows API (windows.h) to center the text output in the console window?
Or a function from another library, or a general possibility?
Currently I inserted several control characters, but depending on the resolution and size of the window it doesn't fit.
printf ("\n\t\t\t\t --Men\x81--\n\n\t\t\t 1: Neue Spielrunde\n\t\t\t 2: Charaktere laden\n\t\t\t 3: Spielrunde speichern\n\t\t\t 4: Programm beenden\n\n");

Taking reference of this answer:
#include <windows.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
void print_spaces(int n) {
for (int i = 0; i < n; i++) printf(" ");
}
int main(void) {
CONSOLE_SCREEN_BUFFER_INFO csbi;
int columns, rows, cols_by_2;
// Get console window attributes - no. of columns in this case
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
cols_by_2 = columns / 2;
// Put all options in an array
char options[4][100] = {"1: Neue Spielrunde", "2: Charaktere laden",
"3: Spielrunde speichern", "4: Programm beenden"};
char menu_header[5] = "Men\x81";
int len_header_by_2 = strlen(menu_header) / 2;
print_spaces(cols_by_2 - len_header_by_2);
printf("%s\n", menu_header);
// Find max half-length of string
int max_val = INT_MIN;
for (int i = 0; i < 4; i++) {
int len_str = strlen(options[i]) / 2;
if (max_val < len_str)
max_val = len_str;
}
// Compute spaces to add for max half-length string
int no_of_spaces = cols_by_2 - max_val;
// Print all options using computed spaces
for (int i = 0; i < 4; i++) {
print_spaces(no_of_spaces);
printf("%s\n", options[i]);
}
return 0;
}
Here's the link where I tested the underlying logic (excluding computing window attributes): http://ideone.com/KnPrct

You can actually take full control of the graphics on a win32 console if you wish. Effectively you end up calling AllocConsole, and then FillConsoleOutputAttribute to set the colour attributes of the text, and FillConsoleOutputCharacter to specify the characters to display. It does however mean you end up avoiding cout/cin/printf/scanf entirely, which may or may not be an issue

Related

How can I print a variable size "string" in C using a for loop?

So I started learning C last week and I'm trying to write a very simple program that prints a pyramid of # characters depending on user input (pyramid height). I was able to write a working code declaring an array with size = maximum height allowed to the user but now I want to do it without fixing the char array to a specified size, this is, I want to update the size of the array for each level of the pyramid (for each for loop passing). The program output look like this:
The code for the above image is:
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
int main(void)
{
int h;
do
{
h = get_int("Height of Pyramid: ");
}
while (h < 1 || h > 8);
char string[h*2+2];
for (int i = 0; i < (h*2)+1; i++)
{
string[i] = ' ';
}
for (int i = 0; i < h; i++)
{
string[(h-1)-i] = '#';
string[(h+2)+i] = '#';
printf("%s\n",string);
}
}
As you can see, every level of the pyramid has the same size. What I want to do know is: if the user input is height = 4, the first printed array (top of the pyramid) should have size=6 (2 blank spaces, 1 #, two blank spaces, 1 #) and the last printed array (the base of the pyramid) should have size 8 (3 #, two blank spaces, 3 #). From what I have readed so far I understand that I can't modify the size of an array in C, so I need to allocated memory and use pointers to make the trick, but I haven't being able to understand how to do this. Below is the code I have writed so far, is basically the same thing as the previous one but I know my array definition is wrong.
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
int main(void)
{
int h;
do
{
h = get_int("Height of Pyramid: ");
}
while (h < 1 || h > 8);
char* string = malloc((h*2+2)*sizeof(char));
for (int i = 0; i < h; i++)
{
int t = 0;
do
{
string[(h+2)+t] = '#';
string[(h-1)-t] = '#';
t++;
}
while (t <= i);
printf("%s\n",string);
}
free(string);
}
The output of the previous code is next, and as you can see it prints a bunch of empty pyramid levels and some # characters at the base of the pyramid. I will appreciate any guide regarding how to solve this.
You can use realloc() in the loop to increase the size of the array.
You also need to add 1 to the allocation for the string's null terminator, and then append that to the array.
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <cs50.h>
int main(void)
{
int h;
do
{
h = get_int("Heigh of Pyramid: ");
}
while (h < 1 || h > 8);
// Create initial string filled with spaces
char* string = malloc(h + 2);
memset(string, ' ', h+2);
for (int i = 0; i < h; i++)
{
string = realloc(string, h + 2 + i + 1 + 1); // + 1 because i is zero-based, + 1 for null terminator
string[h-1-i] = '#';
string[h+2+i] = '#';
string[h+2+i+1] = '\0';
printf("%s\n",string);
}
free(string);
}
#include <stdio.h>
int main(void) {
int h = 7;
char blocks[h];
memset(blocks,'#',h);
for(int i=0; i<h; ++i)
{
printf("%*.*s %.*s\n",h, i+1,blocks, i+1, blocks);
}
return 0;
}
Output
Success #stdin #stdout 0s 4268KB
# #
## ##
### ###
#### ####
##### #####
###### ######
####### #######

TF Lite C API crashes on second iteration

I am trying to use the C API of TF Lite to execute the inference cyclically, e.g. I set up the interpreter and feed him inputs every second or so to get predictions.
For this purpose, I have built libtensorflowlite_c.so via bazel. As documented here, I try to do the inference like this, but inside a for loop to simulate the cyclic execution:
#include "tensorflow/lite/c/c_api.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[]) {
for(int i = 0; i < 3; i++)
{
printf("Iteration: %d\n", i);
float input[49] = { 0.0 };
TfLiteModel* model = TfLiteModelCreateFromFile("model.tflite");
TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
TfLiteInterpreterOptionsSetNumThreads(options, 2);
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
TfLiteInterpreterAllocateTensors(interpreter);
TfLiteTensor* input_tensor = TfLiteInterpreterGetInputTensor(interpreter, 0);
TfLiteTensorCopyFromBuffer(input_tensor, input, 49 * sizeof(float));
TfLiteInterpreterInvoke(interpreter);
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
float output[49];
TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));
printf("Output: \n\n");
for (int j = 0; j < 49; j++) {
printf("%d: %f\n", j, output[j]);
}
TfLiteInterpreterDelete(interpreter);
TfLiteInterpreterOptionsDelete(options);
TfLiteModelDelete(model);
}
return 0;
}
The first iteration runs fine and returns something. But on the second iteration, I get a SegFault when calling TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));. Reason for this is that the previous function TfLiteInterpreterGetOutputTensor returns a nullpointer.
I expected to run this multiple times without any problems, as I destroy all old instances of variables at the end of the for-loop and thus start a fresh interpreter everytime. Obviously, this is not the case.
Can somebody provide any guidance on this? Also, I know that I probably do not have to create an interpreter on every iteration, but I wanted to make sure that everything is created new when I start over again.
EDIT:
I tried rewriting the code to exclude unnecessary parts from the actual loop:
#include "tensorflow/lite/c/c_api.h"
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char* argv[]) {
float input[49] = {0.0};
float output[49] = {[0 ... 48] = 2.5};
TfLiteModel* model = TfLiteModelCreateFromFile("VariationalAutoencoder_440.tflite");
TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate();
TfLiteInterpreterOptionsSetNumThreads(options, 2);
TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model, options);
TfLiteInterpreterAllocateTensors(interpreter);
TfLiteTensor* input_tensor = TfLiteInterpreterGetInputTensor(interpreter, 0);
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
for(int i = 0; i < 3; i++)
{
printf("\nIteration: %d\n", i);
TfLiteTensorCopyFromBuffer(input_tensor, input, 49 * sizeof(float));
TfLiteInterpreterInvoke(interpreter);
TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));
printf("Output: \n");
for (int j = 0; j < 49; j++)
{
printf("%02d: %f\n", j, output[j]);
}
}
TfLiteInterpreterDelete(interpreter);
TfLiteInterpreterOptionsDelete(options);
TfLiteModelDelete(model);
return 0;
}
Remove all variable declarations outside and prior to the for loop, eg:
int main (int argc, char* argv[]) {
float input[49] = { 0.0 };
float output[49] = {0.0};//also needs to be initialized
//and others...
for(int i = 0; i < 3; i++)
{
printf("Iteration: %d\n", i);
....
Do the same for any calls that are creating re-usable objects, or allocating memory. Re-declaring re-usable objects in a loop (without freeing them before re-declare) can have similar results to calling malloc in a loop rather than using realloc for subsequent calls.
Your code snippet shows that you have created and deleted the following inside the loop:
TfLiteInterpreterDelete(interpreter);
TfLiteInterpreterOptionsDelete(options);
TfLiteModelDelete(model);
Calling this in a loop may also be problematic.
TfLiteTensor* input_tensor = TfLiteInterpreterGetInputTensor(interpreter, 0);
input_tensor, I believe should be created once, then, in the loop, resized as needed.
From the link you provide:
// NOTE: After a resize, the client *must* explicitly allocate tensors before
// attempting to access the resized tensor data or invoke the interpreter.
// REQUIRES: 0 <= input_index < TfLiteInterpreterGetInputTensorCount(tensor)
TFL_CAPI_EXPORT extern TfLiteStatus TfLiteInterpreterResizeInputTensor(
TfLiteInterpreter* interpreter, int32_t input_index, const int* input_dims,
int32_t input_dims_size);
Edit: One other item that seems odd:
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
The modifier const seems an odd bedfellow to output_tensor. It would seem if this variable will change inside the loop, then it should not be modified to const.
Your code is running well if TfLiteInterpreterGetOutputTensor use index below TfLiteInterpreterGetOutputTensorCount.
Maybe the tensor index 14 should be 13, but this depends on your model.
Adding some check like :
int count = TfLiteInterpreterGetOutputTensorCount(interpreter);
printf("output tensor count:%d\n", count);
if (count > 14) {
const TfLiteTensor* output_tensor = TfLiteInterpreterGetOutputTensor(interpreter, 14);
float output[49];
TfLiteTensorCopyToBuffer(output_tensor, output, 49 * sizeof(float));
printf("Output: \n\n");
for (int j = 0; j < 49; j++) {
printf("%d: %f\n", j, output[j]);
}
}

Progress Bar in C for an arbitrary long execution -- CONSOLE

I have tried my best to search not only stackOverflow but other website as well but could not find something to match my needs. What I am requesting is to be able to display a progress bar (e.g. Progress: ####.........). I don't really care for the % at the moment.
Now lies the problem. I can not simply do a 0-100 for loop as the code I wish to have executed and tracked lies within a while loop that runs for an arbitrary time (problem size depends on input of user thus, is not constant).
I have thought of keeping track of the number of iterations within an int variable and try to do a modulo by 2, 50 or 100 but as I have said, the number of iterations depends on the users input and thus, only manageable under specific conditions. No other output but the progress bar is done so I do a simple printf('#'); inside the while loop and all the pretty stuff outside it.
This is also a personal preference but don't mind if not included, I would like the progress bar to be 50 characters long so 100% execution = 50 '#' characters accordingly.
Any help is kindly appreciated.
So i wrapped the code from before nicelly and here is what i ended up with.
I used a little bit of oop concept and simulated the class of a ProgressBar. Here is how i designed the code for the ProgressBar:
struct tagProgressBarData
{
unsigned long nMaxLen;
unsigned long nCurLen;
char FillChr;
char EmptyChr;
char LeftMargin;
char RightMargin;
};
typedef struct tagProgressBarData PBD;
void InitProgressBar(PBD* p, unsigned long MaxLen, char Left, char Right, char Fill, char Empty);
void DrawProgressBar(PBD* p);
Before jumping to the definitions of InitProgressBar() and DrawProgressBar(), this is how you should use what i've made. Here is an example:
int main()
{
PBD data;
/** You can chose other characters and change the length too! */
InitProgressBar(&data, 50, '[', ']', '#', '.');
/** Now we do something which takes some time. */
/** Let's just calculate some random cubes. */
/** The N you talked about. */
unsigned int N;
printf("How many numbers to compute: ");
scanf("%u", &N);
printf("Calculating the cubes of the first %u numbers.\n", N);
DrawProgressBar(&data);
for(unsigned int i = 1; i <= N; i++)
{
unsigned int CubeResult = i*i*i;
unsigned long nProgress = ( ((unsigned long long)i) * data.nMaxLen) / N;
if (nProgress != data.nCurLen)
{
data.nCurLen = nProgress;
DrawProgressBar(&data);
}
}
return 0;
}
And now, the definition of the function that prints the progress bar:
void DrawProgressBar(PBD* p)
{
/** Move to the beginning of the line. */
printf("\r");
/** Print the left margin char. */
printf("%c", p->LeftMargin);
/** Make sure that MaxLen >= CurLen */
if (p->nMaxLen < p->nCurLen)
p->nCurLen = p->nMaxLen;
/** Print the progress with the Fill char. */
for(unsigned long i = 0; i < p->nCurLen; i++)
printf("%c", p->FillChr);
/** Complete whats left with the Fill char. */
for(unsigned long i = 0; i < p->nMaxLen - p->nCurLen; i++)
printf("%c", p->EmptyChr);
/** Print the right margin char. */
printf("%c", p->RightMargin);
}
I have also used this function to make my code in main more compact:
void InitProgressBar(PBD* p, unsigned long MaxLen, char Left, char Right, char Fill, char Empty)
{
p->nMaxLen = MaxLen;
p->nCurLen = 0;
p->LeftMargin = Left;
p->RightMargin = Right;
p->FillChr = Fill;
p->EmptyChr = Empty;
}
If you want to have some text before the progress bar but on the same line (something like Progress: [######.............]) you have to replace the printf("\r"); from the DrawProgressBar() with a for loop so you move back exactly the length of the progress bar.
Also, you need some variable (let's say bDrawn) which will tell you if the progress bar has been drawn at least once, so that the for loop will not move the cursor over the existing text at the left of the progress bar.
After trial and error, I may have found a solution but would like to check against someone.
Assuming these variables (all of type int):
num_iterations = 0, MAX_PROGRESS = 100, BAR_LENGTH = 50, num_items = N
I have printed a '#' character on:
if ((iteration / BAR_LENGTH) % (MAX_PROGRESS * BAR_LENGTH * num_items) == 0)
and get my desired result:
|<------------- Enumeration Complete ------------->|
|##################################################| COMPLETED
Though this gradually builds up, it is not of the form
|<------------- Enumeration Complete ------------->|
|##################################................|
Anything I can do with \r or \b?
I have also done this but seems to be very dependent on the number of items.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int MAX_PROGRESS = 100;
int BAR_LENGTH = 0; // Length of Header
int num_items = 30;
void delay(int milliseconds) {
// Storing start time
clock_t start_time = clock();
// looping till required time is not achieved
while (clock() < start_time + milliseconds);
}
void initialiseProgressBar(char left, char right, char fill) {
printf("%c", left);
for (int i = 0; i < BAR_LENGTH; i ++) {
printf("%c", fill);
}
/** Print the right first (end of line) and then again the left (start of line)
* as the \r will be placed over it and rewrite from there resulting in one
* character less
*/
printf("%c\r%c", right, left);
}
void drawProgressBar(char c) {
// Print according to BAR_LENGTH
for (int i = 0; i < 100; i ++) {
double progress = (i / BAR_LENGTH) % (MAX_PROGRESS * BAR_LENGTH * num_items);
if (progress == 0) {
printf("%c", c);
delay(25);
}
// Redraw the stdout stream to show progressing bar
fflush(stdout);
}
}
int main(int argc, char* argv[]) {
// Header
char* header = "|<------------- Progress Bar ------------->|\n";
printf("%s", header);
BAR_LENGTH = strlen(header) - 3; // Account for newline and right character characters
initialiseProgressBar('[', ']', '.');
drawProgressBar('#');
// Footer -- TODO Find better way to finish this without hard coding
printf("] COMPLETED\n");
return 0;
}
Assuming you know the number of items you are calculating against (e.g. sorting a list, calculating different things etc), this should come in handy :).

Randomly Pair Teams From Text File Twice [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm fairly new to C programming and I'm attempting to complete this random pairing program but I'm having issues with starting it. Basically, the program needs to read in the 3 letter team names from a text file, place them into an array, and then randomly pair teams against each other. There are two rounds and in the second round, there cannot be any rematches. Additionally, teams from the same school cannot play against each other. Teams from the same school share the same first character and line in the text file. Can anyone help me with how to code this? :) Here is the text file named provisions.txt:
ABA ABC ABD ABG
BAA BAB BAC
CAB CBA
DAB DBC DBE DBA
EAB
FAB FAC FAA
GAB GAA
HAA HAB
IAB
JAA
KAA
LAL LAB
MAA MAB MBA MUM
NAN NAB
My code so far is:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main()
{
// Read characters from text file into array
FILE *file = fopen("provision.txt", "r");
char teamList[115];
char teams[32][4]; // Holds team names
int i;
for(i = 0; i < 32; i++){
fscanf(file, "%s", teams[i]);
}
for(i = 0; i < 32; i++){
printf("%s \n", teams[i]); // Test to make sure teams are read in
}
// Clean up
fclose(file);
return 0;
}
If possible, I would like to store the output of both rounds in text files named round1_pairings.txt and round2_pairings.txt.
This program attempts to solve a few subtle problems such as random selection bias, backing out of dead-end matching attempts, etc. It is not guaranteed to terminate in the case where a given round cannot be paired due to insufficient teams from other schools, which is more likely to occur at higher numbers of rounds (unlikely with only two rounds and many schools).
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NAMELEN 3
#define ROUNDS 2
#define RETRIES 10 // max attempts before restarting matching
#define STR_HELPER(x) #x // http://stackoverflow.com/a/5459929/4323
#define STR(x) STR_HELPER(x)
#define NAMEPRINTF "%" STR(NAMELEN) "s"
typedef char team_t[NAMELEN + 1];
typedef struct
{
team_t team;
team_t opponents[ROUNDS];
} pairing_t;
// the first round is round=0
// when round>0, prior round matches will be prevented from recurring
void make_matches(pairing_t* pairings, size_t count, size_t round)
{
// clip random() range to avoid bias toward first teams
long randmax = LONG_MAX - LONG_MAX % count - 1;
begin:
for(size_t ii = 0; ii < count; ++ii) {
if(pairings[ii].opponents[round][0]) continue; // already paired
//printf("matching: %s\n", pairings[ii].team);
unsigned retry = 0;
while(retry < RETRIES) {
long rand = random();
if (rand > randmax) continue; // avoid bias
pairing_t *opp = &pairings[rand % count];
if(opp->team[0] == pairings[ii].team[0]) { // same school
++retry;
continue;
}
if(opp->opponents[round][0]) continue; // already paired
size_t prior;
for(prior = 0; prior < round; ++prior) {
if(!memcmp(opp->team, pairings[ii].opponents[prior], sizeof(team_t))) {
break;
}
}
if(prior != round) continue; // duplicate pairing
//printf("match made: %s %s\n", opp->team, pairings[ii].team);
memcpy(pairings[ii].opponents[round], opp->team, sizeof(team_t));
memcpy(opp->opponents[round], pairings[ii].team, sizeof(team_t));
break;
}
if(retry == RETRIES) { // matching failed, start again
for(size_t ii = 0; ii < count; ++ii) {
memset(pairings[ii].opponents[round], 0, sizeof(team_t));
}
goto begin;
}
}
}
int main(void)
{
srandom(time(NULL));
FILE *file = fopen("provision.txt", "r");
size_t capacity = 15; // arbitrary initial size
pairing_t *pairings = calloc(capacity, sizeof(pairing_t));
if(!pairings) abort();
size_t count = 0;
while(fscanf(file, NAMEPRINTF, pairings[count].team) != EOF) {
//printf("%s\n", pairings[count].team);
++count;
if(count >= capacity) { // expand array
capacity *= 2;
pairings = realloc(pairings, capacity * sizeof(pairing_t));
if(!pairings) abort();
memset(&pairings[count], 0, (capacity - count) * sizeof(pairing_t));
}
}
for(size_t round = 0; round < ROUNDS; ++round) {
make_matches(pairings, count, round);
}
for(size_t ii = 0; ii < count; ++ii) {
printf("%s %s %s\n", pairings[ii].team, pairings[ii].opponents[0], pairings[ii].opponents[1]);
}
free(pairings);
fclose(file);
return 0;
}
The output is a simple table with three columns: the team playing, their first opponent, and their second opponent. I'm sure you can figure out how to write these to separate files as required.

Fixing small error in output using arrays in C

I am currently working on a project that when given a main function which calls another function confab(), outputs a serious of characters. The question refers to some made up race. They choose an integer nRows between 2 and half the length of the message, e.g. a message of length 11 would allow values of nRows in the range 2 to 5. The message is then written down the columns of a grid, one character in each grid cell, nRows in each column, until all message characters have been used. This may result in the last column being only partially filled. The message is then read out row-wise.
For example the message "Don't wait until the last day before starting" with a nRows of 3 would return:
D'wtnlhltabo ai.ota t ea yersrnn iuit sd fettg
I have written code that does this fairly efficiently, however I have been provided with a test case that i cannot seem to work out.
char buffer[8] = {'*','*','*','*','*','*','*','*',};
confab("ABCDEF.", 3, buffer);
printf("%s\n", buffer);
Is this example, and the output it should give is:
AD.BECF
However my code returns:
AD.BECF*
Due to the extra * in the outText buffer not being replaced with a character. I have tried many things such as removing this extra *, or re initializing the outText to be the same length as the inText (within the code as the main case provided is not allowed to be edited), however nothing thus far has made a difference.
I was wondering if there would be a quick edit I could apply to my code that would perform this change, as I cannot seem to find a way apart from editing the main input which is not allowed.
My code is as follows:
/*
* Confabulons.c
* A program to encode for the Confabulons
*
* August 8th 2015
*/
#include <stdio.h>
#include <string.h>
//A simple function confab which given input text, and a number
//of rows, returns a phrase in the Confabulons encoding scheme.
void confab(const char inText[], int nRows, char outText[])
{
int count = 0;
int i = 0;
int z = 0;
int len = strlen(inText);
while (z < nRows)
{
while (((int)inText[count] > 0) && (count < len))
{
outText[i] = inText[count];
i ++;
count = count + nRows;
}
z ++;
count = z;
}
}
At the end of the function add line:
outText[i] = '\0';
You need to validate the length of the outText string, try:
void confab(const char inText[], int nRows, char outText[])
{
int count = 0;
int i = 0;
int z = 0;
int len = strlen(inText);
int lenOut = strlen(outText);
while (z < nRows)
{
while (((int)inText[count] > 0) && (count < len))
{
outText[i] = inText[count];
i ++;
count = count + nRows;
}
z ++;
count = z;
}
if (i < lenOut) {
outText[i] = '\0';
}
}

Resources