简体   繁体   English

sprintf附加了额外的字符

[英]sprintf prepends extra character

I decided to write a binary converter, the code is small and simple , it takes an integer and is supposed to output a char* with the resulting binary string. 我决定编写一个二进制转换器,代码又小又简单,它需要一个整数,并且应该将char *与生成的二进制字符串一起输出。

The issue here seems to be that the last sprintf always seems to double the last prepended character. 这里的问题似乎是最后一个sprintf似乎总是最后一个前置字符的两倍。

For example if the answer is meant to be 1001001 it will print 11001001 or if it is supposed to be -10 it prints --10, the latter being particularly peculiar as that one isn't even in a loop. 例如,如果答案是1001001,则它将打印11001001,或者如果答案是-10,则打印--10,后者特别奇怪,因为它甚至不在循环中。

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

void bin_string( char** buffer ,int num ){

    bool neg = false;

    if ( num < 0 ){
        neg = true;
        num = ~num+1;
    }

    if( num == 0 )
        sprintf( *buffer, "%d", 0 );

    while( num > 0 ){

        int rem = num%2;

        sprintf( *buffer, "%d%s", rem, *buffer );

        printf("iteration: %s rem: %d\n", *buffer, rem );
        num = num/2;
    }

    if( neg )
        sprintf( *buffer, "-%s", *buffer );
}

int main( int argc, char** argv ){

    char* a = malloc( sizeof(char)*64 );
    bin_string( &a, 73 );

    printf("Result %s\n",a ); /* output is 11001001 but should be 1001001*/

    return 0;
}

The declaration of sprintf() in C99 and beyond is: C99及更高版本中sprintf()的声明为:

    int sprintf(char *restrict s, const char *restrict format, ...);

You are violating the restrict part of that declaration. 您违反了该声明的restrict部分。 You are using, for example: 您正在使用,例如:

sprintf(*buffer, "-%s", *buffer);

This is trying to modify the buffer in situ, and is undefined behaviour. 这是试图原位修改缓冲区,并且是未定义的行为。 You're lucky you're getting such nearly sane results — or maybe unlucky. 您很幸运,您获得了如此近乎理智的结果-也许很不幸。 You can't use the target buffer in the trailing arguments to the call to sprintf() . 您不能在sprintf()调用的尾随参数中使用目标缓冲区。

I suppose sprintf is just not smart enough to insert buffer into itself. 我认为sprintf不够聪明,无法在自身中插入缓冲区。 You probably need to have two buffers and swap them. 您可能需要两个缓冲区并进行交换。

The answer is that you're invoking undefined behavior when you're sprintf() ing *buffer to itself. 答案是,当您将sprintf()对其自身使用*buffer时,您正在调用未定义的行为 What you should do instead is something like: 相反,您应该做的是:

void bit_string(char *buf, int n)
{
    int nbits = sizeof(n) * CHAR_BIT;
    int i;
    for (i = 0; i < nbits; i++) {
        buf[i] = '0' + ((n >> (nbits - i - 1)) & 1);
    }
    buf[nbits] = 0;
}

(Yes, I've also taken care of efficiency, readability and portability for you - you're welcome.) (是的,我也为您提供了效率,可读性和可移植性-不用客气。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM