Как динамически центрировать выравнивание текста в строке типа char *, чтобы вместить в общей сложности 16 пробелов в C? - PullRequest
0 голосов
/ 08 мая 2019

Я пытаюсь выровнять строки по центру в 16 местах, чтобы в итоге распечатать их на ЖК-дисплее 16x2. Значения извлекаются из базы данных и помещаются в глобальную переменную, которая постоянно обновляется.

Значения в базе данных уже представлены в строковом формате.

Что я хотел бы сделать, так это после получения значения из БД обновить глобальную переменную, чтобы она содержала строку с центром в 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 = пробел ххххх = строка из db

Если длина строки нечетная Я ожидаю, что результат будет [00xxxxxxxxxxxxx0]

если длина строки четная Я ожидаю, что на выходе будет [00xxxxxxxxxxxx00]

Ответы [ 3 ]

2 голосов
/ 08 мая 2019

Это простая 6-ти строчная функция.symetry дает вам опцию

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;
}

или с возможностью выделить память для баффа (если вы передаете 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;
}
0 голосов
/ 08 мая 2019

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);
}
0 голосов
/ 08 мая 2019

Вы можете сделать это по-другому (без использования функции 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 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);                                                                                                                                   
}        

edit: есть интерфейс для работы функции sprintf (как вы изначально хотели).Чтобы увидеть это, обратитесь к ответу Рыба-меч

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...