【问题标题】:Why does fprintf print extra values为什么 fprintf 打印额外的值
【发布时间】:2011-07-22 19:07:20
【问题描述】:

我想对包含字段编号和线路类型的标签进行编码,以用于协议缓冲区。我现在遇到的问题是,每当我的“标签”值低于“8”时,fprintf 就会在正确值旁边写入附加值。即打印 38c0 3 而不是 38。如果 tag 的值为 8 或更高,则脚本可以正常工作。下面是省略了无关行的代码。

int uint32_pack (uint8_t *fieldnumber, uint32_t value, uint8_t *out);

int main(){

uint32_t initvalue = 2;
int return_rv;
uint8_t *tag = (uint8_t *) malloc(sizeof(uint8_t));    
uint8_t *tempout= (uint8_t *) malloc(sizeof(uint32_t));
*tag = 7; //value to be encoded (won't work for values less than 8)

return_rv = uint32_pack (tag, initvalue, tempout);

free(tempout);

    }

/* === pack() === */
/* Pack an unsigned 32-bit integer in base-128 encoding, and return the number
 of bytes needed: this will be 5 or less. */

int uint32_pack (uint8_t *fieldnumber, uint32_t value, uint8_t *out)
{
  unsigned rv = 0;
  FILE *wiretypetag;
  int secondaryvalue;

  wiretypetag = fopen("wiretype.txt","w");


    //encodes wire type and the field number
    if (*fieldnumber <16){
       *fieldnumber <<= 3;
       fprintf(wiretypetag,"%x",fieldnumber[0]);
       }
    if (*fieldnumber < 32 && *fieldnumber > 15){
       *fieldnumber <<= 3;
       secondaryvalue = 0x01;
       fprintf(wiretypetag,"%x %x",fieldnumber[0],secondaryvalue);
           }
    if (*fieldnumber < 48 && *fieldnumber > 31){
        *fieldnumber += 0x10;
        *fieldnumber &= 0x1F;
        *fieldnumber <<= 3;
        secondaryvalue = 0x02;
        fprintf(wiretypetag,"%x %x",fieldnumber[0], secondaryvalue);
        }       
    if (*fieldnumber < 64 && *fieldnumber > 47){
        *fieldnumber &= 0x1F;
        *fieldnumber <<= 3;
        secondaryvalue = 0x03;
        fprintf(wiretypetag,"%x %x",fieldnumber[0], secondaryvalue);
        }       

  /* assert: value<128 */   
    out[rv++] = value;


    if (rv == 1){         
           fprintf(outfile,"%x",out[0]);
           }
    if (rv == 2){
           fprintf(outfile,"%x %x",out[0], out[1]);
           }    
    if (rv == 3){
           fprintf(outfile,"%x %x %x",out[0],out[1],out[2]);
           }
    if (rv == 4){
           fprintf(outfile,"%x %x %x %x",out[0],out[1],out[2],out[3]);
           }
    if (rv == 5){
           fprintf(outfile,"%x %x %x %x %x",out[0],out[1],out[2],out[3],out[4]);
           }

    fclose(wiretypetag);

    return rv;
}

【问题讨论】:

  • 如果检查..看起来像一个错字,您没有在第一个取消引用字段编号? if (fieldnumber &lt;16){
  • @JohnKlehm 抱歉,这是我在文本框中输入的错误
  • 另外你在第一行使用 %d 而不是 %x 像其他地方一样,是故意的吗? fprintf(wiretypetag,"%d",fieldnumber[0]);
  • 是的,我只是在做一些故障排除,看看是否是问题所在
  • 这个问题的答案对于以后遇到这个问题的人来说没什么用。投票关闭过于本地化。

标签: c file-io printf


【解决方案1】:
 if (fieldnumber <16){

应该是

if (*fieldnumber <16){

【讨论】:

  • 问题已经解决,所以这不是问题的全部。
  • +1 不是因为它现在回答了这个问题,而是它在 OP 编辑​​之前回答了。
【解决方案2】:

您可以在以下位置使用else 来简化代码:

//encodes wire type and the field number
if (*fieldnumber <16){
   *fieldnumber <<= 3;
   fprintf(wiretypetag,"%d",fieldnumber[0]);
   }
if (*fieldnumber < 32 && *fieldnumber > 15){
   *fieldnumber <<= 3;

替换为:

//encodes wire type and the field number
if (*fieldnumber < 16) {
   *fieldnumber <<= 3;
   fprintf(wiretypetag, "%d", fieldnumber[0]);
   }
else if (*fieldnumber < 32) {
   *fieldnumber <<= 3;
...

这是一个常见的习语,你应该在适当的时候使用 - 就像现在一样。它将提高代码的易读性。

这可能不是问题的全部;可能不是。

问题说明

事实上,使用else if 链可以更正代码。因为第一个if&lt;&lt;=运算符修改了*fieldnumber,所以在计算第二个条件时,*fieldnumber不再是7而是56,所以

的条件
if (*fieldnumber < 64 && *fieldnumber > 47){

也被执行,打印出更多信息。

else if 链将通过确保只执行一个替代方案来解决这个问题。


因为你有:

unsigned rv = 0;

[...]
/* assert: value<128 */   
out[rv++] = value;

if (rv == 1){         
       fprintf(outfile,"%x",out[0]);
       }

这个fprintf()应该被执行,但是下面的rv等于2、3、4、5永远不应该被执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-28
    • 1970-01-01
    • 2021-06-27
    • 2020-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多