Преобразование значений вектора в указатель на символ для записи в системный вызов - PullRequest
0 голосов
/ 05 февраля 2019

У меня возникли проблемы с использованием write().У меня есть vector<long>, в котором есть несколько разных длинных значений.Моя конечная цель - преобразовать этот вектор в указатель на символ, чтобы я мог передать его в write и вывести значения в стандартный вывод.

Вот мой код:

void print_vector(vec* v)
{
    int init_capacity = 10;
    char* output = (char*) malloc(init_capacity*sizeof(char));
    int cols = (int) sqrt(v->size);


    for (int i = 0; i < v->size; i++)
    {
        if(i==init_capacity)
        {
            init_capacity *= 2;
            output = (char*)realloc(output, init_capacity*sizeof(char));
        }
        const int n = snprintf(NULL, 0, "%l", v->data[i]);
        char buffer[n+1];
        int c = snprintf(buffer, n+1, "%l", v->data[i]);
        if ((i + 1) % cols == 0) {
            strcat(buffer, '\n');
        }

        output[i] = buffer;
    }

    write(1, output, init_capacity);
//    for (int i = 0; i < v->size; i++)
//    {
//        printf("%ld ", v->data[i]);
//        if ((i + 1) % cols == 0) {
//            puts("");
//        }
//    }

}

Iсначала инициализируйте символ *, который я планирую передать в качестве буфера write.Я даю ему начальную емкость 10, и когда я перебираю вектор и передаю его значения в свой буфер output, я перераспределяю пространство, если у меня заканчивается.

В моем цикле for ясначала проверьте, исчерпал ли мой output пробел и перераспределил, если мне нужно.

Затем я загружаю элемент ith моего вектора в buffer (не путать с output).Я делаю это потому, что хочу добавить "\n" в конце последнего значения в столбце (это должно выглядеть как матрица).Вы увидите это во втором операторе if в коде, где я объединяю "\ n" в буфер.

Я делаю что-то очень неправильно, потому что у меня есть ошибка.

Есть две причины, по которым я думаю, что это происходит:

  1. Я подозреваю, что что-то не так с buffer.Я не знаю, что это может быть, хотя ... может быть, char buffer[n+1] не счастлив?Я действительно не уверен.

  2. Возможно, я неправильно понял значения для strcat.Буфер там не принадлежит?

  3. Я вполне уверен, output[i]= buffer неверно.

Мне нужна помощь с этим, и, надеюсь, некоторые объяснения,

Это домашнее задание .Вы не должны давать мне точный ответ.Хотя было бы неплохо, если бы было какое-то объяснение - то, что я действительно ищу, это пример.

Я включил в комментарии ниже write(), что я хочу сделать.

Редактировать:

Новый код:

void print_vector(vec* v)
{
    int cols = (int) sqrt(v->size);
    for (int i = 0; i < v->size; i++)
    {
        int n = snprintf(NULL, 0, "%ld", v->data[i]);
        char buffer[n+1];
        sprintf(buffer, n+1, "%ld", v->data[i]);
        if ((i + 1) % cols == 0) {
            strcat(buffer, "\n");
        } else {
            strcat(buffer, " ");
        }

        write(1, buffer, n+1);
    }


//    for (int i = 0; i < v->size; i++)
//    {
//        printf("%ld ", v->data[i]);
//        if ((i + 1) % cols == 0) {
//            puts("");
//        }
//    }
}

Когда я запускаю gdb, я получаю такой вывод:

program received signal SIGSEGV, Segmentation fault.
__strchrnul_sse2 () at ../sysdeps/x86_64/multiarch/../strchr.S:32
32  ../sysdeps/x86_64/multiarch/../strchr.S: No such file or directory.
(gdb) 

Что, как мне кажется, бесполезно ...

Некоторые предупреждения, которые я получаю при компиляции:

$ make
gcc -g -o ctp transpose.c vec.c -lm
transpose.c: In function ‘print_vector’:
transpose.c:59:25: warning: passing argument 2 of ‘sprintf’ makes pointer from integer without a cast [-Wint-conversion]
         sprintf(buffer, n+1, "%ld", v->data[i]);
                         ^
In file included from transpose.c:2:0:
/usr/include/stdio.h:320:12: note: expected ‘const char * restrict’ but argument is of type ‘int’
 extern int sprintf (char *__restrict __s,

1 Ответ

0 голосов
/ 05 февраля 2019

Нет необходимости использовать snprintf() во второй раз, вы можете просто использовать sprintf().Первый вызов сказал вам, как долго будет длиться вывод, и вы выделили достаточно места для этого, когда объявили buffer.Поэтому вам не нужно беспокоиться о переполнении буфера, когда вы на самом деле пишете его.

И если вы все же используете snprintf(), вы не должны использовать n+2 в качестве ограничения.Так как вам нужно освободить место для новой строки, вы должны использовать n+1.

В операторе if требуется предложение else, которое записывает пробел, так что у вас будет что-то между столбцами вmatrix.

    if ((i + 1) % cols == 0) {
        strcat(buffer, "\n");
    } else {
        strcat(buffer, " ");
    }

Обратите также внимание, что вторым аргументом strcat() должна быть строка, а не char.

Если вы действительно хотите, чтобы это выглядело как хорошая матрица,Вы должны указать ширину для вывода в строке формата, чтобы все столбцы были одинакового размера.Это также означает, что вам не нужно указывать размер buffer динамически, он просто должен быть достаточно большим для этой ширины.

...