当前位置:C++技术网 > 资讯 > 如何将整数型字符串的内容复制到字符型字符串中

如何将整数型字符串的内容复制到字符型字符串中

更新时间:2016-11-07 00:13:47浏览次数:1+次

有一个整数数组,要求将其格式化为字符串,每个数字以逗号分开。

完成函数:
void  to_string(const int* arr,  int size,  char* output)
{
}
例如,
int  arr[4] = { 18, 987, 1235, -911 };
char buf[512];
to_string(arr, 4, buf);

则buf被格式化为字符串 "18, 987, 1235, -911"

我的代码

void  to_string(const int* arr,  int size,  char* output)
{
const int* str = arr;
char* buf = output;
for(int i = 0; i<size; i++)
{
buf[i] = str[i];
}
for(int i = 0; i<size; i++)
{
printf("%c,",buf[i]);
}
}
int main()
{
int  arr[4] = { 18, 987, 1235, -911 };
    char buf[512];
    to_string(arr, 4, buf);
    return 0;
}
问题:输出乱码


C++技术网解答:

    通过仔细分析你写的代码,得知,你对这个程序并没有理解到位,代码没有达到目的,而不仅仅是乱码的问题。通过这个程序,可以看到学习中的一些问题。

    下面我对你的程序代码和知识,解决思路进行一个全面的分析,让你知其然知其所以然。

    为了鼓励你,先给你看看程序的运行效果图:

程序的运行效果图

    这里输出的是一串字符串,而字符串的内容就是整型数组初始化部分的形式。而这个输出的结果,只不过就是打印了buf的内容而已。

    下面开始一点点的分析。

    “如何将整数型字符串的内容复制到字符型字符串中”,对于提问的这点,要纠正一下。字符串没有整数型字符串和字符型字符串的说法,所有的字符串都是字符组成的。字符串不过就是一个字符数组后面加了一个空字符\0形成的。你的意思是,你所指的整数型字符串是整型数组。整型数组没有字符串的说法。这是概念上理解模糊,请体会。

    先给出你的代码,看看代码的错误:

void  to_string(const int* arr,  int size,  char* output)
{
    const int* str = arr;//多余
    char* buf = output;//多余
    for(int i = 0; i<size; i++)
    {
        buf[i] = str[i];//直接将整型数组的值复制到了字符数组里。不需要。
    }
    for(int i = 0; i<size; i++)
    {
        printf("%c,",buf[i]);//格式化指示符不对。而且没有将内容格式化到output里,做了无用功。
    }
}
     标注多余的两行,完全没有必要。因为参数就可以操作,不必再创建一个指针变量来操作。参数里的指针就指向了被传递进来的内存。虽然没有错,但是多余了。

    第一个for循环数组,直接将整型数组的内容复制到了字符数组中了。这个不知道用意,没有理解题目的意思。第一个for循环没有任何用。可以不要。你的意思是格式化,其实只是复制了内容而已,没有实现格式化的目的。

    第二个for循环,将输出的缓存output格式化打印出来。然而也没有实现你自己的意图。这里只是单个字符的格式化并打印。因为第一个循环是将arr数组的数值复制给了output,所以前面4个字节就是arr的4个值。然而这4个值在ASCII表里对应的字符,你可以查一查是什么。要么就是非正常的显示字符,要么就超过了ASCII编码最大值。不乱码都不行。

    所以,这个函数代码,没有实现题目的要求。问题在于,题目没有理解正确,还有代码编写不够熟练,基础知识不扎实。

    看了问题,下面看正确的答案应该如何做出来!注意,这里是如何做出来,而不是正确的答案是什么!希望你跟着写代码的思路来看,这样形成一个顺畅的思维,而不是记答案或者硬套答案去强行理解。

    题目给定了arr整型数组。然后要将数组的四个数字,依次格式化为对应的数字字符组成的字符串,并且是4个数字字符串通过逗号连接成一个字符串。其实提问的问题就是要努力表达这个意思,可能还是理解的不够深入,没有达到效果,反而犯了语法错误。不过没有关系,出现了错误,才能真正学到东西。这是一个好的开始。

    那么根据这个题目要求,我们要做的事情有:

1.将整型数字格式化为对应的数字字符组成的字符串,而且用逗号相隔,并且最后一个数字后面没有逗号。

2.将四个数字格式化成的字符串拼接为一个完整的字符串。

    将问题拆分为两个小问题,下面来逐个突破。

问题1:

    格式化整数,不就是printf做的事情吗?比如:

int num=100;
printf("%d",num);
     这样打印出来的就是100这个字符串,或者叫做''''1'''',''''0'''',''''0''''三个字符组合。反正打印在控制台程序上面的都是字符,显示出来的只有字符,只不过是数字字符而已。这是我们再熟悉不过的了。printf就是用来格式化输出的。

     然而,我们这里并不是要直接格式化打印出来,这里要的是格式化到字符数组buf里。如果你不知道sprintf的存在,可能这里确实会犯难。

    sprintf和printf一样的格式化,只是sprintf的第一个参数是一个字符数组地址或者叫做char*指向的内存。后面的参数就和printf一样使用了。这就是格式化到缓冲或者叫做格式化到内存的做法。

    我们这一步是要将四个数字格式化到字符串,即格式化到字符数组里。我们就需要创建一个临时的字符数组来存放每一个格式化的字符串。这个临时字符数组每次在使用时要清零一下,以免干扰后面的格式化。我们用循环来格式化每一个数字。

    而且最后一个数字最后不能跟上逗号,所以你要判断一下循环的最后一个数字,特别处理一下。

    那么这一个问题的实现代码为:

char tmp[10];
for(int i = 0; i<size; i++)
{
    memset(tmp,0,10);
    if (i==size-1)
    {
        sprintf(tmp,"%d",arr[i]);
    }
    else
    {
        sprintf(tmp,"%d,",arr[i]);
    }
}
     因为后面要考虑直接在格式化数字成字符串后,紧接着就将字符串拼接到输出的字符数组中,所以这里不单独创建一大堆的临时字符数组。而且,因为你不知道整型数组的大小,也不能预先创建指定个数的字符数组哦。tmp字符数组要用memset清空的目的可以让字符数组有空字符结尾,以免乱码出现,另一方面是防止上一个字符串干扰下一个字符串。

问题2:

    要拼接字符串,C语言中使用strcat。strcat两个参数,第一个是目标字符数组,第二个参数是源字符数组。效果是将第二个参数的字符串接在第一个字符串后面。比如:

char buf[100] = "123";
strcat(buf,"456");//得到的buf是:"123456"
     如果不知道这个函数的存在,拼接字符串又是一个很大的障碍。当然,你也可以自己实现一个字符串拼接函数。就是将第一个字符数组进行遍历,找到空字符后,然后开始将第二个字符数组的字符依次复制接在第一个字符串后面,而且第二个字符串的第一个字符放在第一个字符串的空字符上。

    不管怎么样,能实现就行了。我们用C语言的strcat就比较方便。


    所以将两个问题的代码合并成一个,就是题目需要的代码了。代码如下:

void  to_string(const int* arr,  int size,  char* output)
{
    char tmp[10];
    memset(output,0,512);//要么output内存在外面被初始化为全0了,要么要给定大小。我们这里采用给定大小方式清零一下
    for(int i = 0; i<size; i++)
    {
    memset(tmp,0,10);
    if (i==size-1)
    {
        sprintf(tmp,"%d",arr[i]);
    }
    else
    {
        sprintf(tmp,"%d,",arr[i]);
    }
        strcat(output,tmp);
    }
}
     至于要不要对output清零,就看外部有没有事先清零。反正output必须清零一次,否则会引起乱码,因为会没有空字符。甚至会引起程序崩溃。如下图所示:

内存不清零引起的崩溃

    而这些问题也只有在实际编程中你才能发现。所以需要多编程写代码,才能学得好代码。

    下面是所有的完整代码:

#include "stdio.h"
#include "string.h"
void  to_string(const int* arr,  int size,  char* output)
{
    const int* str = arr;//多余
    char* buf = output;//多余
    for(int i = 0; i<size; i++)
    {
        buf[i] = str[i];//直接将整型数组的值复制到了字符数组里。不需要。
    }
    for(int i = 0; i<size; i++)
    {
        printf("%c,",buf[i]);//格式化指示符不对。而且没有将内容格式化到output里,做了无用功。
    }
}
void  to_string2(const int* arr,  int size,  char* output)
{
    char tmp[10];
    memset(output,0,512);//要么output内存在外面被初始化为全0了,要么要给定大小。我们这里采用给定大小方式清零一下
    for(int i = 0; i<size; i++)
    {
    memset(tmp,0,10);
    if (i==size-1)
    {
        sprintf(tmp,"%d",arr[i]);
    }
    else
    {
        sprintf(tmp,"%d,",arr[i]);
    }
        strcat(output,tmp);
    }
}
int main()
{
    int  arr[4] = { 18, 987, 1235, -911 };
    char buf[512];
    to_string2(arr, 4, buf);
    //打印出buf的内容看看
    printf(buf);
    printf("\n");
    return 0;
}
     请自己运行一下完整的代码,细细体会。