открыть через snprintf - PullRequest
       23

открыть через snprintf

0 голосов
/ 27 марта 2019

У меня проблемы с компиляцией моей программы, которая, в противном случае, работает нормально, хотя при попытке скомпилировать предупреждение

при попытке сконденсировать strcpy & strcat в snprintf (удалить ненужные строки кода)

передача аргумента 2 из snprintf делает целое число из указателя без приведения

представляет себя. Я пытался найти других людей с этой проблемой, однако, как только они адаптировались, их решения не работают с моим кодом

fileDir определяется при запуске программы как: char fileDir[1000];

event->name - имя файла (и его расширение), например, picture1.jpg.

hashDirectory - это "/home/user/Documents/_Hash".

FILE *ftest2=fopen(snprintf(fileDir, "%s: %s: %s", hashDirectory, event->name, ".txt"), "wt");

Я могу открыть файл, но только тогда, когда использую strcpy и strcat - от этого я и пытаюсь избавиться.

1 Ответ

1 голос
/ 27 марта 2019

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

А пока мы пропустим fopen и сосредоточимся на snprintf.snprintf аналогично printf, за исключением того, что сначала необходимо передать два дополнительных аргумента: char *, указывающий, где хранить визуализированные символьные данные, и size_t, указывающий, сколько места доступно в char *.Идиоматический способ сделать это (предполагая, что char[] является пунктом назначения) состоит в использовании sizeof() следующим образом:

int res = snprintf(fileDir, sizeof(fileDir), /* Other arguments omitted */);

snprintf возвращает количество напечатанных символов (как int).Если это число больше или равно sizeof(fileDir), то все, что находится в fileDir, будет усечено (но всегда будет NULL прекращено).

if (res >= sizeof(fileDir)) {
    /* fileDir contains an incomplete path, handle this as an error */
}

Наконец, потому что возвращаемое значение snprintf - это int, вы не можете передать это как первый аргумент fopen, потому что он ожидает, что первый аргумент будет const char *.Так что это должны быть отдельные шаги.

Сказав все это, способ, которым вы строите путь, также кажется неправильным.В полном примере ниже я исправил это:

FILE *ftest2;

int res = snprintf(fileDir, sizeof(fileDir), "%s/%s.txt", hashDirectory, event->name);
if (res >= sizeof(fileDir)) {
    fprintf(stderr, "The pathname was truncated. Cannot proceed.\n");
    return -1;
}

ftest2 = fopen(fileDir, "wt");
if (!ftest2) {
    fprintf(stderr, "Failed to open `%s': %s\n", fileDir, strerror(errno));
    return -1;
}

/* Rest of your code */

Важное замечание: если бы первым аргументом snprintf был указатель на динамически распределенную память (т. Е. От malloc), вы бы неон не сможет использовать sizeof(), и вместо этого ему придется явно передавать размер динамически выделенной области.sizeof() вычисляется во время компиляции (игнорируя VLA ), а не во время выполнения.

(Вам понадобятся #include string.h и errno.h дляstrerror() позвоните на работу, если хотите использовать эту часть)

...