如何在C中向字符数组中添加逗号

如何在C中向字符数组中添加逗号,c,arrays,struct,C,Arrays,Struct,所以我有一个char数组,它当前保存一个人信息的结构。 比如说, struct Person{ char first_name[100]; char last_name[100]; char phone[13]; }; struct Person* arr[] = {("John", "Doe", "831.563.3642"), ("Julie", "Dee", "542.865.4644") }; 我试图让它打印成这样的文件 John, Doe, 831.563.3642 Julie,

所以我有一个char数组,它当前保存一个人信息的结构。 比如说,

struct Person{
char first_name[100];
char last_name[100];
char phone[13];
};

struct Person* arr[] = {("John", "Doe", "831.563.3642"), ("Julie", "Dee", "542.865.4644") };
我试图让它打印成这样的文件

John, Doe, 831.563.3642
Julie, Dee, 542.865.4644
int strlen(char* str) {
    int count = 0;
    while (str[count]) {
        count++;
    }
    return count;
}
到目前为止,这是我的代码(在放入文件时尝试添加逗号)

void打印(文件*FILE\u out,结构人*p1[]{
size_t len=sizeof(p1)/sizeof(p1[0]);
对于(i=0;i
结构Person*arr[1]等同于Person arr也等同于Person**arr 我想你不是这个意思。去掉指针:D

现在关于字符串的一些非常重要的事情。。。strlen函数是导致缓冲区溢出错误的#1原因-切勿在没有某种限制的情况下使用strlen

此外,内部字符串长度如下所示

John, Doe, 831.563.3642
Julie, Dee, 542.865.4644
int strlen(char* str) {
    int count = 0;
    while (str[count]) {
        count++;
    }
    return count;
}
注意这几乎就是你的函数了? 您的功能可以更改为

char* makeString(char* str) {
    char out[] = ""
    int count = 0;
    while (str[count]) {
        out[count] = str[count];
        count++;
    }
    out[count] = ',';
    out[count + 1] = 0;
    return out;
}
让我们来讨论一下这个问题——首先,注意while循环,它只在找到0时结束?这是制作bug的好方法。所有人要做的就是给一个名字太长一点,然后砰的一声!没有终点0

现在假设我连续多次调用你的函数。。。 你每次都在字符串中循环!!! 换句话说,我遍历字符串“john”的循环。这是通过while循环的4次。它还生成了一个字符[6]来保存这些内容,因为john是4,而“,”是1,“字符串的结尾”标记是0

现在我们再次添加到字符串中。我们迭代“john”the“,”并添加“Joe”。这意味着我们需要一个长度为9的新长字符[]。现在,当循环命中时,我们迭代“john”和“doe”9次。然后我们一次又一次地这样做。我们在john上迭代了很多次。太多次了

现在,安全的方法是:D

//Create a string of a known length that can hold all the data
//Now we only need to create a char buffer once instead of multiple times
//In a regular computer, it is better to waste space than CPU time :D (in this case anyway...)
char printString[sizeof(arr.first_name) + 2 + sizeof(arr.last_name) + 2 + sizeof(arr.phone) + 1];
//Remember where we last wrote, and where we are in our current copy
int position = 0;
int i = 0;
//While it is not the end of the string, and we have not gone over the longest possible length...
while (arr[0].first_name[i] && i < sizeof(arr[0].first_name)) {
    //Copy the character
    printString[position] = arr.first_name[i];
    //Move to the next spot in both character buffers
    position++;
    i++;
}
//Add our comma and space
prinstString[position] = ',';
printtString[position + 1] = ' ';
position = position + 2;
int i = 0;
while (arr[0].last_name[i] && i < sizeof(arr[0].last_name)) {
    printString[position] = arr.last_name[i];
    position++;
    i++;
}
prinstString[position] = ',';
printtString[position + 1] = ' ';
position = position + 2;
int i = 0;
while (arr[0].phone[i] && i < sizeof(arr[0].phone)) {
    printString[position] = arr.phone[i];
    position++;
    i++;
}
prinstString[position] = 0;

我想我现在编辑完了

你可能让事情变得比你需要的更艰难。填充了
struct Person
后,为了获得所需的输出,只需输出由
逗号和
空格分隔的结构成员即可。简单的
printf
就可以了,例如

struct Person p1 = { "John", "Doe", "831.563.3642" };
...
printf ("%s, %s, %s", p1.first, p1.last, p1.phone);
上述结果将是:

John, Doe, 831.563.3642
您永远不能执行
char new[]=”
--创建大小为1的数组
new
,其中包含
“\0”
字符。(不好的名字也可以选择,<代码>新< /COD>是C++中的KEWWORD,应该避免使用它作为变量名)。一旦声明并初始化了自动存储持续时间为1的数组(其大小是固定的),该数组将持续一段时间,并且无法扩展。您需要使用
malloc
动态分配存储,以便以后能够使用
realloc
调整存储的大小

如果要创建一个包含逗号分隔值的附加数组,则需要声明具有存储的数组,以最初保存最大的
名字、姓氏和
电话,例如
字符buf[100+100+13+4]
(对于要插入的
对,“
也要插入+4),现在您可以使用
sprintf
简单地写入新数组

下面是一个简短的示例,它显示了使用
printf
直接输出和使用
sprintf
创建新数组(
buf
)。无论是直接输出逗号空格分隔的值,还是先将它们存储在缓冲区中,结果都是相同的。函数
csvperson()
将目标数组和指向填充结构的指针作为参数,将结构的成员以逗号和空格分隔写入数组,例如

#include <stdio.h>

#define MAXNM 100   /* if you need a constant, #define one (or mroe) */
#define MAXPH  13

typedef struct {            /* using a typedef allows you to later omit the */
    char first[MAXNM],      /* 'struct' prefix in your declarations and */
         last [MAXNM],      /* parameter lists */
        phone [MAXPH];
} person;

char *csvperson (char *dest, person *p)
{
    if (!dest)
        return NULL;

    sprintf (dest, "%s, %s, %s", p->first, p->last, p->phone);

    return dest;
}

int main (void) {

    char buf[2 * MAXNM + MAXPH + 4];
    person p1 = { "John", "Doe", "831.563.3642" };

    printf ("direct output : %s, %s, %s\nbuffer output : %s\n", 
            p1.first, p1.last, p1.phone, csvperson (buf, &p1));
}
仔细检查一下,如果你还有其他问题,请告诉我


阵列示例

要对数组使用上述相同的方法,请执行以下操作:

int main (void) {

    char buf[2 * MAXNM + MAXPH + 4];
    person p1[] = { {"John", "Doe", "831.563.3642"},
                    {"Jane", "Doe", "832.563.3643"},
                    {"Mary", "Jane", "303.331.3333"} };
    int n = sizeof p1 / sizeof *p1;

    for (int i = 0; i < n; i++)
        printf ("\ndirect output : %s, %s, %s\nbuffer output : %s\n", 
                p1[i].first, p1[i].last, p1[i].phone, csvperson (buf, p1+i));
}

一般来说,不要担心组合/连接等。。你可以简单地写出来的东西(无论是文件、终端等等)

不要粉饰它:这段代码的错误多于正确。你有a吗,因为相信这一点:C不是一种你反复尝试才能成功的语言。无论如何,如果您只想在输出中的数据元素之间打印逗号分隔符,那么为什么不这样做呢。例如,在打印而不是制作一堆数据的不必要副本的代码中?
void prnperson(struct Person*p){printf(“%s,%s,%s\n”,p->first_name,p->last_name,p->phone);}
@WhozCraig我必须让它打印第一个元素(即名称),然后是一个逗号,那么,相同模式中的以下元素不是吗?我认为在一个函数中完成所有操作并返回它会更容易。另外,我已经学习C语言大约一个月了,对所有的错误感到非常抱歉。更改为
void print(FILE*FILE\u out,struct Person p1[]){..
正如我的回答下面的评论,声明中没有
'*'
。或者
void print(FILE*FILE\u out,struct Person*p1){..
没有
[]
——同时调用
“*”
[…]
指示一级指针间接寻址——数组只需要一级指针。在有足够的时间回答任何其他问题后,如果您仍然需要帮助,请查看:。重要的不是您选择哪个答案,而是如果您的问题已被回答,您可以通过单击答案左上角的旁边(按数字)来指示这将使用绿色复选标记将答案标记为您选择的答案。我了解printf实现了什么,但是,我正在尝试将其写入另一个文件,而不仅仅是写入控制台,因此我尝试使用fputs来实现这一点。那么,它仍然会是类似的吗?为什么不使用
fprintf
来写入f直接ile???
fprintf(文件指针,“%s,%s”,p1.first,p1.last,p1.phone);
int main (void) {

    char buf[2 * MAXNM + MAXPH + 4];
    person p1[] = { {"John", "Doe", "831.563.3642"},
                    {"Jane", "Doe", "832.563.3643"},
                    {"Mary", "Jane", "303.331.3333"} };
    int n = sizeof p1 / sizeof *p1;

    for (int i = 0; i < n; i++)
        printf ("\ndirect output : %s, %s, %s\nbuffer output : %s\n", 
                p1[i].first, p1[i].last, p1[i].phone, csvperson (buf, p1+i));
}
fprintf (fileptr, "%s, %s, %s\n", p1[i].first, p1[i].last, p1[i].phone);