在C中不使用sprintf将整数转换为字符串
可以在C中将整数转换为字符串,而无需在C中不使用sprintf将整数转换为字符串,c,type-conversion,printf,C,Type Conversion,Printf,可以在C中将整数转换为字符串,而无需sprintf?有一个非标准函数: char *string = itoa(numberToConvert, 10); // assuming you want a base-10 representation 编辑:看来你需要一些算法来实现这一点。下面是如何在base-10中: #include <stdio.h> #define STRINGIFY(x) #x #define INTMIN_STR STRINGIFY(INT_MIN) i
sprintf
?有一个非标准函数:
char *string = itoa(numberToConvert, 10); // assuming you want a base-10 representation
编辑:看来你需要一些算法来实现这一点。下面是如何在base-10中:
#include <stdio.h>
#define STRINGIFY(x) #x
#define INTMIN_STR STRINGIFY(INT_MIN)
int main() {
int anInteger = -13765; // or whatever
if (anInteger == INT_MIN) { // handle corner case
puts(INTMIN_STR);
return 0;
}
int flag = 0;
char str[128] = { 0 }; // large enough for an int even on 64-bit
int i = 126;
if (anInteger < 0) {
flag = 1;
anInteger = -anInteger;
}
while (anInteger != 0) {
str[i--] = (anInteger % 10) + '0';
anInteger /= 10;
}
if (flag) str[i--] = '-';
printf("The number was: %s\n", str + i + 1);
return 0;
}
#包括
#定义STRINGIFY(x)#x
#定义INTMIN\U STR字符串化(INT\U MIN)
int main(){
整数=-13765;//或其他
如果(一个整数==INT_MIN){//处理角情况
put(INTMIN_STR);
返回0;
}
int标志=0;
char str[128]={0};//即使在64位上也足以容纳int
int i=126;
if(整数<0){
flag=1;
anInteger=-anInteger;
}
而(整数!=0){
str[i-->=(整数%10)+“0”;
一个整数/=10;
}
如果(标志)str[i-->='-';
printf(“号码是:%s\n”,str+i+1);
返回0;
}
您可以在可用的情况下使用itoa。如果在您的平台上不可用,则可能会对以下实现感兴趣:
用法:
char *numberAsString = itoa(integerValue);
更新
根据R.的评论,可能值得修改现有的itoa实现以接受调用者的结果缓冲区,而不是让itoa分配并返回缓冲区
这样的实现应该同时接受缓冲区和缓冲区的长度,注意不要写超过调用方提供的缓冲区的末尾。下面是一个示例,说明它的工作原理。给定一个缓冲区和一个大小,我们将继续除以10,并用数字填充缓冲区。如果缓冲区中没有足够的空间,我们将返回
-1
int
integer_to_string(char *buf, size_t bufsize, int n)
{
char *start;
// Handle negative numbers.
//
if (n < 0)
{
if (!bufsize)
return -1;
*buf++ = '-';
bufsize--;
}
// Remember the start of the string... This will come into play
// at the end.
//
start = buf;
do
{
// Handle the current digit.
//
int digit;
if (!bufsize)
return -1;
digit = n % 10;
if (digit < 0)
digit *= -1;
*buf++ = digit + '0';
bufsize--;
n /= 10;
} while (n);
// Terminate the string.
//
if (!bufsize)
return -1;
*buf = 0;
// We wrote the string backwards, i.e. with least significant digits first.
// Now reverse the string.
//
--buf;
while (start < buf)
{
char a = *start;
*start = *buf;
*buf = a;
++start;
--buf;
}
return 0;
}
int
整数到字符串(char*buf,size\t bufsize,int n)
{
字符*开始;
//处理负数。
//
if(n<0)
{
如果(!bufsize)
返回-1;
*buf++='-';
bufsize——;
}
//记住弦的开始…这将开始发挥作用
//最后。
//
开始=buf;
做
{
//处理当前数字。
//
整数位数;
如果(!bufsize)
返回-1;
数字=n%10;
如果(数字<0)
数字*=-1;
*buf++=数字+'0';
bufsize——;
n/=10;
}而(n);
//终止字符串。
//
如果(!bufsize)
返回-1;
*buf=0;
//我们将字符串向后写入,即首先使用最低有效数字。
//现在倒转字符串。
//
--buf;
while(启动
不幸的是,在你需要编造一串字母数字字符的情况下,上面的答案没有一个能完全解决问题。我见过一些非常奇怪的情况,特别是在面试和工作中
代码中唯一不好的部分是,您需要知道整数的边界,以便正确分配“字符串”
尽管C被认为是可预测的,但如果您在编码过程中迷失方向,它在大型系统中可能会有奇怪的行为
下面的解决方案返回一个带有空终止字符的整数表示字符串。这不依赖于任何外部函数,也适用于负整数
#include <stdio.h>
#include <stdlib.h>
void IntegertoString(char * string, int number) {
if(number == 0) { string[0] = '0'; return; };
int divide = 0;
int modResult;
int length = 0;
int isNegative = 0;
int copyOfNumber;
int offset = 0;
copyOfNumber = number;
if( number < 0 ) {
isNegative = 1;
number = 0 - number;
length++;
}
while(copyOfNumber != 0)
{
length++;
copyOfNumber /= 10;
}
for(divide = 0; divide < length; divide++) {
modResult = number % 10;
number = number / 10;
string[length - (divide + 1)] = modResult + '0';
}
if(isNegative) {
string[0] = '-';
}
string[length] = '\0';
}
int main(void) {
char string[10];
int number = -131230;
IntegertoString(string, number);
printf("%s\n", string);
return 0;
}
#包括
#包括
void IntegertoString(字符*字符串,整数){
if(number==0){string[0]='0';return;};
整数除法=0;
int-modResult;
整数长度=0;
int为负=0;
整数;
整数偏移=0;
copyOfNumber=数字;
如果(数字<0){
isNegative=1;
数字=0-数字;
长度++;
}
while(copyOfNumber!=0)
{
长度++;
copyOfNumber/=10;
}
for(divide=0;divide
太好了,我已经删除了我现在已经过时的评论。:)<代码>一个整数=-一个整数代码>可能会失败,因为字符串化方法无效INT_MIN
不能定义为简单的十进制字符串。它一定是某种类型的非平凡表达式。更好的方法是始终使用范围更大的负数进行运算,或者以安全的方式转换为无符号类型进行运算。INT\u MIN
需要limits.h
。我想这可能有点太复杂了,看看我的答案。@H2CO3-我有点喜欢我的。我知道128字节“对任何人都足够好”,但检查缓冲区大小是一个好习惯。我也喜欢在缓冲区的开始处而不是结尾处进行写入。+1,我肯定更喜欢缓冲区大小感知解决方案,而不是一个明目张胆地预先分配的、具有任意“足够大”大小的固定缓冲区。OTOH,这确实可以做一些简化…-1,itoa
不仅是非标准的,而且使用静态缓冲区,使得任何使用它的代码不仅是非线程安全的,而且如果不立即复制结果,结果可能会在别处被破坏。正确地做到这一点几乎是一个简单的过程,所以像这样糟糕的解决方案永远不应该被使用。@R..:我确实提到过你可以在可用的地方使用itoa,并提供了一个实现,以防它在给定的平台上不可用。OP没有说明任何螺纹安全要求。但是,如果需要线程安全,那么将静态缓冲区转换为线程分配的存储或基于堆的存储是很简单的。尽管如此,我还是用一个不使用静态缓冲区的实现替换了链接的实现。itoa
的主要问题并不是它不标准(正如您向我们展示的,替换率下降)
int i = 24344; /*integer*/
char *str = itoa(i);
/*allocates required memory and
then converts integer to string and the address of first byte of memory is returned to str pointer.*/