[英]How to dynamically center align text in a char * string to fit in a total of 16 spaces in C?
我正在嘗試將字符串在總共16個空格中居中,以最終在16x2 LCD顯示器上打印它們。 這些值從數據庫中獲取,並放入一個不斷更新的全局變量中。
數據庫中的值已經是字符串格式。
我想做的是從數據庫獲取值之后,更新全局變量以包含以16個空格為中心的字符串。
我知道使用全局變量可能不是最佳做法,但是忽略了有沒有辦法做到這一點?
char * systemInfoValues[5] = {" "," "," "," "," "}
for(int i=0; i< 5; i++){
systemInfoValues[i] = PQgetvalue(res,i,0); //get the value from db;
int len = strlen(systemInfoValues[i]);
char tmp[20];
sprintf(tmp,"%*s", (17-len)/2 + len, systemInfoValues[i]);
strcpy(systemInfoValues[i],tmp);
}
0 =空格xxxxx =來自數據庫的字符串
如果字符串的長度為奇數,我希望輸出為[00xxxxxxxxxxxxx0]
如果字符串的長度是偶數,我希望輸出為[00xxxxxxxxxxxx00]
簡單的6行功能。 對稱性給您選擇
char *centerinstring(char *buff, size_t len, const char *str, int symetry)
{
size_t strl = strlen(str);
size_t pos = (len - strl) / 2 + (strl & 1) * !!symetry;
memset(buff,' ', len);
buff[len] = 0;
memmove(buff + pos, str, strl);
return buff;
}
int main()
{
char buff[11];
printf("|%s|\n", centerinstring(buff, 10, "1234567", 1));
printf("|%s|\n", centerinstring(buff, 10, "1234567", 0));
return 0;
}
或選擇為buff分配內存(如果您傳遞NULL
char *centerinstring(char *buff, size_t len, const char *str, int symetry)
{
size_t strl = strlen(str);
size_t pos = strl / 2 + (strl & 1) * !!symetry;
buff = buff ? malloc(len + 1) : buff;
if(buff)
{
memset(buff,' ', len);
buff[len] = 0;
memmove(buff + pos, str, strl);
}
return buff;
}
您可以用另一種方式(不使用sprintf函數)來執行此操作。 我不知道允許您執行sprintf函數的任何接口,但是您可以使用簡單的變量strcpy解決問題。
這是一個可以解決您問題的主程序,它本身已在文檔中進行了記錄,因此您應該能夠了解如何將此應用到代碼中:
#include <stdio.h>
#include <string.h>
/* This simple program would transfer the original string that is in the
* out_value to be centralized in this variable. */
int main(void) {
char out_value[17] = "1234567891";
char temp[20] = {0};
int first_index = 0;
int string_length = 0;
/* Copy the string to the temp variable, to modify the chars in
* out_value. */
strcpy(temp, out_value);
/* Find out the index for the first char to be placed in the centralized
* string. */
string_length = strlen(temp);
first_index = (16 - string_length) / 2;
/* Set all the values of the out_value to be the wanted value of space (here
* it is 0 for visualizing, it can be space to not be present). */
memset(out_value, '0', 16);
/* Copy the original string back, moving the start of it, so it would be
* centralized. */
strncpy(&(out_value[first_index]), temp, string_length);
/* Print the string. */
printf("%s", out_value);
}
修改您的代碼以使其與此配合使用時,代碼將如下所示:
char * systemInfoValues[5] = {NULL}
for(int i=0; i< 5; i++){
systemInfoValues[i] = PQgetvalue(res,i,0); //get the value from db;
int len = strlen(systemInfoValues[i]);
char tmp[20];
int first_index = 0;
strcpy(tmp, systemInfoValues[i]);
first_index = (16 - len) / 2;
memset(systemInfoValues[i], ' ', 16);
strncpy(&(systemInfoValues[i][first_index]), tmp, len);
}
請注意,我更改了systemInfoValues值的初始化。 初始化時,將空字符串放在此處。 請注意,這是一個壞習慣。 將空字符串放在那里(或帶有單個空格的字符串)會為此字符串分配內存(您將永遠不會使用)。
您沒有在PQgetvalue函數中包含定義,但是假設它會返回一個char指針,那么這應該可以工作。 但是,此代碼也會改變全局值。 如果您不想更改它,則不應將結果放在此處,而是在對結果進行任何更改之前將結果復制到字符串中。 修改代碼后,它應如下所示:
char systemInfoValues[5][17] = {{0}}
for(int i=0; i< 5; i++){
char *global_reference = PQgetvalue(res,i,0); //get the value from db;
int len = strlen(systemInfoValues[i]);
char tmp[20];
int first_index = 0;
strcpy(tmp, global_reference);
first_index = (16 - len) / 2;
memset(systemInfoValues[i], ' ', 16);
strncpy(&(systemInfoValues[i][first_index]), tmp, len);
}
編輯:顯然,有一個sprintf函數可以使用的接口(如您最初想要的那樣)。 要查看它,請參閱劍魚的答案
sprintf()
舒適度:
#include <assert.h>
#include <string.h>
#include <stdio.h>
void center(char *dst, char *src, size_t width)
{
assert(dst && src && width);
size_t src_len = strlen(src);
if (src_len >= width) {
*dst = '\0';
return;
}
int right = (int)(width - src_len) / 2;
int left = right + (int)src_len;
right -= (src_len & 1);
sprintf(dst, "%*s%*s", left, src, right, "");
}
int main(void)
{
char destination[17];
center(destination, "12345678901234", sizeof(destination));
printf("\"%s\"\n", destination);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.