Лучшая/обычная практика для разграничения значений в C при их печати

Я попробовал использовать функцию поиска, но нашел только вопросы, касающиеся чтения в файлах с разделителями-запятыми/пробелами.

Мой вопрос, однако, как вы обычно подходите к этому. Скажем, у меня есть список/массив/... значений, например {1, 2, 3, 4}, и я хочу напечатать их с разделителем.

Самый простой вариант будет примерно таким:

#include <stdio.h>

int main(void)
{
     char list[] = {1, 2, 3, 4};
     unsigned int i;

     for (i = 0; i < 4; ++i)
     printf("%d, ", list[i]);

     return 0;
}

который, очевидно, напечатает «1, 2, 3, 4,». У меня проблема с запятой и пробелом в конце.

Теперь я мог бы сделать:

#include <stdio.h>

int main(void)
{
    char list[] = {1, 2, 3, 4};
    unsigned int i;

    for (i = 0; i < 4; ++i)
    {
        printf("%d", list[i]);
        if (i < 3)
            printf(", ");
    }

    return 0;
}

Но это не похоже на лучший способ сделать это. Может ли кто-нибудь указать мне правильное направление? Спасибо

PS: Нет, я обычно не задаю значения жестко кодом
PPS: Нет, я не пытаюсь писать файлы .csv ;)


person melzer    schedule 14.10.2010    source источник
comment
возможный дубликат Печать списков с запятыми C++   -  person Jonathan Leffler    schedule 17.10.2013


Ответы (7)


Я использую эту идиому:

assert(n > 0);
printf("%d", list[0]);
for (i = 1; i < n; ++i)
     printf(", %d", list[i]);

Единственным его недостатком является то, что он плохо масштабируется при n == 0, как простой цикл. В качестве альтернативы можно добавить защиту от n == 0:

if (n > 0)
    printf("%d", list[0]);
for (i = 1; i < n; ++i)
     printf(", %d", list[i]);
person Michał Trybus    schedule 14.10.2010
comment
Спасибо, выглядит очень красиво и аккуратно. - person melzer; 14.10.2010
comment
Другим недостатком является необходимость дублировать тело цикла. - person jamesdlin; 14.10.2010
comment
assert(n > 0); выглядит неправильно, это не обязательное условие для печати содержимого массива. - person Arun; 15.10.2010
comment
Вы можете вполне разумно заменить assert() на if (n > 0) {, за которым следует другой код и }. - person Jonathan Leffler; 15.10.2010

Моя стандартная техника для этого:

const char *pad = "";
for (int i = 0; i < n; i++)
{
    printf("%s%d", pad, list[i]);
    pad = ", ";
}

Иногда начальным значением pad является пробел, двоеточие или что-то еще, что работает в контексте.

person Jonathan Leffler    schedule 14.10.2010
comment
Довольно необычно, мне нравится. +1 - person Michał Trybus; 14.10.2010
comment
Необычно, конечно, но очень хорошая идея. Но я думаю, что буду придерживаться версии Михала Трибуса. - person melzer; 14.10.2010

Я подобрал этот формат с условным оператором из K&R2:

for (i = 0; i < n; i++)
    printf("%d%s", list[i], i+1 < n ? ", " : "\n");
person schot    schedule 14.10.2010
comment
@melzer: Да, второе издание языка программирования C со штампом ANSI C на лицевой стороне. Я только что посмотрел: он используется в разделе 5.10. - person schot; 15.10.2010

Что ж, даже несмотря на то, что уже есть принятый ответ, никто не пришел с очевидным ответом на мой вкус:

#include <stdio.h>
int main(void) {
    unsigned list[] = {1, 2, 3, 4};
    unsigned const n = 4;
    if (n) for (unsigned i = 0; ; ++i) {
        printf("%d", list[i]);
        if (i >= n) break;
        printf(", ");
    }
    printf("\n");
    return 0;
}
person Jens Gustedt    schedule 14.10.2010
comment
Это почти то же самое, что упомянул ОП. - person jamesdlin; 15.10.2010
comment
@jamesdlin: я не знаю, как вы измеряете в значительной степени, но идея состоит в том, чтобы сделать только необходимое количество сравнений без избыточности. С другой стороны, это позволяет избежать дублирования кода печати чисел, как в решении Михала Трибуса. - person Jens Gustedt; 15.10.2010
comment
О, хороший момент. Я упустил этот аспект. Однако вам нужно добавить дополнительную проверку, если список может быть пустым. - person jamesdlin; 15.10.2010

Используйте версию Михала Трибуса или наоборот

for (i = 0; i < (n - 1); ++i) 
{
     printf("%d, ", list[i]);
}
printf("%d", list[n - 1]);
person Himanshu    schedule 14.10.2010

Почему бы не просто еще одну версию, пока мы в ней. Вот что я обычно делаю

for (i=0;i<n;++i)
{
  if (i) printf(", ");
  printf("%d",list[i]);
}
person miked    schedule 14.10.2010

person    schedule
comment
Я хотел проголосовать, потому что это напоминает мне моего преподавателя C. Она любила код, который никто не мог понять. К сожалению, поштучно;( - person Michał Trybus; 14.10.2010