Я пытаюсь выровнять строки по центру в общей сложности 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 = пробел ххххх = строка из БД
Если длина строки нечетная Я ожидаю, что вывод будет [00xxxxxxxxxxxxx0]
если длина строки четная Я ожидаю, что вывод будет [00xxxxxxxxxxxx00]





Вы можете сделать это другим способом (без использования функции 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 (как вы изначально хотели). Чтобы увидеть это, обратитесь к ответу рыба-меч
Это работает, хотя я получаю случайные значения в конце строк. Вывод: 0xxxxxxxxxxxxx00, 000000xxxx0000008G, 00000xxxxxx00000PG
Я не могу это воспроизвести. Вы запускаете мою основную функцию или свой код? Кажется, что что-то работает над терминатором NULL в конце (это произойдет, если длина, которую вы указали, равна 16, а не 17, например).
Позвольте мне попробовать еще раз с 17
17 усугубляет ситуацию, индекс 1 перезаписывает индексы 3,4,5 и добавляет случайные символы
В моем коде кажется, что строки, исходящие из PQGetValue, не действуют как обычные строки. Вот описание того, что возвращает PQGetvalue: «Для данных в текстовом формате значение, возвращаемое PQgetvalue, представляет собой строковое представление значения поля, заканчивающееся нулем».
Я думаю, вам следует изменить свой код, чтобы он работал как мой последний пример, поскольку проблема, похоже, связана с возвращаемым значением PQGetValue, а не с кодом централизации. Если вы можете воспроизвести проблему в основной функции, то она связана с кодом централизации, но если нет, то проблема больше связана с интерфейсом, который вы используете (и PQGetValue), и мне в настоящее время не хватает данные (из вашего вопроса), чтобы решить эту проблему.
Это простая 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;
}
или с возможностью выделения памяти под бафф (если передать 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;
}
Какой вариант симметрии?
если даже вы не можете иметь это одно дополнительное место справа или слева
Ладно, buff здесь — значение базы данных, а str — временная? или наоборот?
неважно
``` char tmp[20]; набор памяти (tmp, ' ', len); тмп[длина] = 0; memmove(tmp+pos,systemInfoValues[i],strl); strcpy(systemInfoValues[i],tmp); ``` Приводит к ошибке seg
использовать функцию как задано.
Функция работает с "1234567", но не с моими строками. Вот описание того, что возвращается из PQGetValue: «Для данных в текстовом формате значение, возвращаемое PQgetvalue, представляет собой строковое представление значения поля, заканчивающееся нулем».
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);
}
Где я могу найти assert.h?
@mmajdalani Это должно быть частью стандартной библиотеки вашего компилятора?
@mmajdalani, если нет, вы можете удалить assert() из функции. Просто убедитесь, что вы не передаете ему указатель NULL.
Хорошо, я проверю это, как только вернусь за свой стол, и отправлю обновление.