我在使用 sprintf() 时遇到了一些困难

时间:2021-05-28 11:53:33

标签: c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>


#define BINARY_ACCURACY 32

int convertDezToDualString(const int number, char stringDualNumber[]){
    int num = number;
    if (number<0){
        //nothing here yet
    } else {
        for (int i = 0; i<BINARY_ACCURACY; i++){
            sprintf(stringDualNumber,"%d%s",num%2,stringDualNumber); 
                   //I think that's the part where the thing happens
            printf("%s",stringDualNumber);    //For Testing purposes
            printf("\n");
            num/=2;
        }

    }
}

int main() {
    char* stringDualNumber= (char*) calloc(BINARY_ACCURACY,sizeof(char));
    const int dezNumber = getInt();    //Gets a decimal number and returns if it's valid
    convertDezToDualString(dezNumber, stringDualNumber);
}

Input:
1234
Output:
00
110
0010
00010
110010
0010010
11010010
111010010
0011010010
00011010010
110011010010
0010011010010
00010011010010
000010011010010
0000010011010010
00000010011010010
000000010011010010
0000000010011010010
00000000010011010010
000000000010011010010
0000000000010011010010
00000000000010011010010
000000000000010011010010
0000000000000010011010010
00000000000000010011010010
000000000000000010011010010
0000000000000000010011010010
00000000000000000010011010010
000000000000000000010011010010
0000000000000000000010011010010
00000000000000000000010011010010
000000000000000000000010011010010

我想知道为什么它总是把最后一个数字输出两次...... 我没想到这种行为。我正在使用 cygwin。当我的输出是 33 而不是 32 位时,我偶然发现了这个问题。所以我让for循环每次迭代都输出字符串。并发现了这个问题。我对 c 很陌生,但以前用过 java。

4 个答案:

答案 0 :(得分:0)

我认为,在您对 sprintf 的调用中,它立即将 num%2 写入 stringDualNumber(通过 %d),然后将结果再次写入同一次调用中,因为它将现在修改的 stringDualNumber 引用到 %s ?

这是您的代码的修改版本,其中包含一个临时字符串来解决此问题:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>


#define BINARY_ACCURACY 32

int convertDezToDualString(const int number, char stringDualNumber[]){
    char tempstr[32];
    int num = number;
    if (number<0){
        //nothing here yet
    } else {
        for (int i = 0; i<BINARY_ACCURACY; i++){
            strcpy(tempstr, stringDualNumber);
            sprintf(stringDualNumber,"%d%s",num%2,tempstr);
                   //I think that's the part where the thing happens
            printf("%s",stringDualNumber);    //For Testing purposes
            printf("\n");
            num/=2;
        }

    }
}

int main() {
    char* stringDualNumber= (char*) calloc(BINARY_ACCURACY,sizeof(char));
    const int dezNumber = 5;    //Gets a decimal number and returns if it's valid
    convertDezToDualString(dezNumber, stringDualNumber);
}

答案 1 :(得分:0)

首先,您应该在开始处终止 stringDualNumber,因为您将它传递给 sprintf() 并带有一个新分配的内存区域。显然你的内存是用零初始化的(所以我猜你正在运行一个调试版本)。

第二:考虑一下 sprintf() 的作用:首先它将 num%2 的值写入您的字符串。之后它会写入字符串本身的内容。但此时您的字符串已经包含新数字。这就是为什么你会看到它两次。

编辑:
第一个循环写
'0' +(现在是字符串)"0" = "00"
第二个循环
覆盖
字符串 '1'(将 "00" 更改为 "10")+(现在是字符串)"10" = "110"
等等……

答案 2 :(得分:0)

您需要分配足够的空间来容纳空终止符。

我不会在这项工作中使用 sprintf 怪物功能。它可以通过更有效的方式实现:

char *convertToBinString(unsigned val, char *buff, int printLeadingZeroes)
{
    unsigned mask = 1 << (sizeof(val) * CHAR_BIT - 1);
    char *wrkbuff = buff ? buff : calloc(sizeof(val) * CHAR_BIT + 1, 1);
    
    buff = wrkbuff;
    if(wrkbuff)
    {
        for(; mask; mask >>= 1)
        {
            if(!printLeadingZeroes) 
            {
                if(val & mask) printLeadingZeroes = 1; 
            }
            if(printLeadingZeroes)
            {
                *wrkbuff++ = val & mask ? '1' : '0';
            }
        }
    }
    return buff;
}

int main(void)
{
    char *buff = NULL;
    int x = 1234;
    printf("%8d in binary is: %s\n", x, (buff = convertToBinString(x, buff, 0)));
    printf("%8d in binary is: %s\n", x, (buff = convertToBinString(x, buff, 1)));
    x = -1234;
    printf("%8d in binary is: %s\n", x, (buff = convertToBinString(x, buff, 0)));
    printf("%8d in binary is: %s\n", x, (buff = convertToBinString(x, buff, 1)));
    free(buff);
}```

https://godbolt.org/z/dc1KxWaqr

答案 3 :(得分:-2)

int convertDezToDualString(const int number, char stringDualNumber[]){
    int num = number;
    for (int i = BINARY_ACCURACY-1; i>=0; i--){
        stringDualNumber[i]=48+(num%2);
        num/=2;
    }
}

我认为一个更好...我知道我分配的太少了。解决这个问题更像是一种绝望的尝试。不管它会给出相同的输出。

相关问题