Вызов printf, snprintf, f_printf, ect с использованием переменных для аргументов printf - PullRequest
0 голосов
/ 14 июня 2019

Исправление опечаток:

В c я хотел бы использовать printf (и его двоюродных братьев) таким образом:

    snprintf(cFormatSpecifier,10,"%s","%2.5f");
    float nData=1.234;
    int *pnData=&nData;
    printf(cFormatSpecifier,*pnData);

Но это не дает никакого вывода.

Было бы удобно, если бы это было возможно, поэтому спецификаторы формата и ссылки на данные, которые должны быть напечатаны, были в наборе переменных.


Я рекомендую "Сохранять это простым", но могуКажется, я не могу забыть о своем воображении.

Мой код сложен со структурой, созданной для массива.

{
    uint16_t nItem;
    char cColumnHeader[20];
    char  *ptrcPrintfFormat;
    uint8_t nDataLen;
    int *ptrToData;

} oKneeTestReportData;

// loaded with (one of 17 array elements):
    snprintf(aKneeTestReportData[i].cColumnHeader,20,"%s","Timestamp");
    aKneeTestReportData[i].ptrcPrintfFormat="%i\0";
    aKneeTestReportData[i].nDataLen=0;  // if string, this is set
    aKneeTestReportData[i].ptrToData=(int*)&oMasterTime.timestamp;

// where oMasterTime.timestamp is one of many variables that change within a processing loop.  In this same loop, I f_printf() a data column for a report:

f_printf(&oSystemInfo.fUtilityFile,aKneeTestReportData[i].ptrcPrintfFormat,*aKneeTestReportData[i].ptrToData);

// where [i] in this instance refers to the aKneeTestReportData element and *aKneeTestReportData[i].ptrToData dereferences.

Поскольку у меня есть aKneeTestReportData [i] .ptrToData, содержащая адреспеременной данных, каким бы ни было ее содержимое, она должна нормально работать с f_printf ().Но вместо этого я ничего не получаю.

Что касается этого замечательного предложения:

float *pnData=&nData;
printf(cFormatSpecifier,*pnData);

В указанной переменной данных есть целые числа, числа с плавающей запятой и строки.Я хочу, чтобы один указатель в моей структуре указывал на переменную данных, и этот указатель должен быть «общим».Может быть, это невозможно?

Есть кое-что просто глупое в том, что я здесь делаю, но не вижу этого (лес и деревья).Собираюсь отказаться от этого метода и просто жестко закодировать мой отчет, но я упрямый ...


ОК.Это работает.

    oKneeTestReportData aKneeTestReportData[2]; 
    // load it
    int ij=0;
    float nfData=123.456;
    snprintf(aKneeTestReportData[ij].cColumnHeader,20,"%s","Timestamp");
    aKneeTestReportData[ij].ptrcPrintfFormat="%i\0";
    aKneeTestReportData[ij].ptrToData=(int*)&oMasterTime.timestamp;

    ++ij;
    snprintf(aKneeTestReportData[ij].cColumnHeader,20,"%s","Float Data");
    aKneeTestReportData[ij].ptrcPrintfFormat="%2.5f\0";
    aKneeTestReportData[ij].ptrToData=(int*)&nfData;

    ij=0;
    char cPrintOut[80];
    while(true)
    {

        printf("Printing first variable [%i] using format[%s] \n\r",oMasterTime.timestamp,aKneeTestReportData[0].ptrcPrintfFormat);

        // compiler warns that format string is not a string literal.. potentially unsecure
        printf(aKneeTestReportData[0].ptrcPrintfFormat,*aKneeTestReportData[0].ptrToData);

        printf("\n\r");

        // my printf doesn't do floats
        snprintf(cPrintOut,80,"Printing second variable [%2.5f] using format[%s] \n\r",nfData,aKneeTestReportData[1].ptrcPrintfFormat);
        printf(cPrintOut);

        // compiler warns that format string is not a string literal.. potentially unsecure
        snprintf(cPrintOut,80,aKneeTestReportData[1].ptrcPrintfFormat,*aKneeTestReportData[0].ptrToData);
        printf(cPrintOut);

        printf("\n\r");

        ++ij;
        if (ij>5)
            break;

        delay_s(1);
        UpdateClockTime();  // updates timestamp
        nfData=nfData+ij;
    }

Вывод:

Printing first variable [1560499764] using format[%i]
1560499764
Printing second variable [123.45600] using format[ f]
123.45600
Printing first variable [1560499806] using format[%i]
1560499806 // debug pause caused time lapse
Printing second variable [124.45600] using format[ f]
124.45600

Я предполагаю, что printf моего спецификатора формата завершился ошибкой, так как он интерпретировался как спецификатор формата в тексте!

Итак, вернемся к моему еще более сложному коду, чтобы узнать, где я его сломал.

Спасибо всем за полезные советы, критику и идеи!

Ответы [ 2 ]

1 голос
/ 14 июня 2019

Вы, вероятно, просто хотите это:

strcpy(cFormatSpecifier, "%2.5f"). 
printf(cFormatSpecifier, nData);     

или

const char *cFormatSpecifier;
...
cFormatSpecifier = "%2.5f"; 
printf(cFormatSpecifier, nData);     
...
printf(cFormatSpecifier, otherData);     
...
cFormatSpecifier = "%5.2f"; 
printf(cFormatSpecifier, nData);     
...

Будьте проще.

1 голос
/ 14 июня 2019

После вашего snprintf переменная cFormatSpecifier должна содержать "%2.5f".Но в вашем выражении printf вы передаете указатель на указатель на число с плавающей точкой, где ожидается "%2.5f", то есть число с плавающей точкой.Напишите ...

printf(cFormatSpecifier,nData);

или

printf(cFormatSpecifier,*pnData);

и все должно работать как положено.

...