使用C中的fprintf写入csv文件时出现奇怪的字符

时间:2018-02-14 01:30:41

标签: c csv printf scanf

我正在尝试使用fprintf将名字,姓氏和电话号码插入CSV文件。 但插入后,每行末尾插入了更多奇怪的字符和逗号,并且在读取文件时会产生问题。

以下是我的代码:

FILE *fp;
    fp = fopen(filePath, "r");
    int i = 0;
***** Writing *****
FILE *fp;
    fp = fopen("input.csv", "a");
    fprintf(fp,"%s %s ,%s\n", firstname, lastname , phone_number);

*****阅读*****

while(!feof(fp)){   
        fscanf(fp, "%s %s,%s", phone_directory[i].First_Name, phone_directory[i].Last_Name, phone_directory[i].Phone_Number);
        printf("%s %s,%s\n", phone_directory[i].First_Name, phone_directory[i].Last_Name, phone_directory[i].Phone_Number);
        i=i+1;
}

*****输入******

//First Entry

abc xyz,65656565

//Second Entry

uvw efg,6979679679

*****输出*****

abc xyz,65656565,
, uvw,
efg,6979679679 ,,
 ,

请帮助!!!

2 个答案:

答案 0 :(得分:0)

当您使用fscanf(fp, "%s %s,%s", phone_directory[i].First_Name, phone_directory[i].Last_Name, phone_directory[i].Phone_Number);读取abc xyz,65656565之类的字符串时,第二个%s会读取整个xyz,65656565部分而不是逗号停止。

为避免这种情况,您可以使用

fscanf(fp, "%s %[^,],%s", phone_directory[i].First_Name, phone_directory[i].Last_Name, phone_directory[i].Phone_Number);

%[^,]表示继续扫描,但不包括遇到,

fscanf()返回成功分配的数量(或出错时为EOF)。您可以检查其返回值(在这种情况下,如果成功,则应为3),以查看是否所有变量都已分配值。

if( fscanf(fp, "%s %[^,],%s", str1, str2, str3)!=3 )
{
    printf("\nSomething went wrong!");
}

为防止溢出,您可能希望以格式字符串指定字段宽度,如

fscanf(fp, "%49s %49[^,],%49s", str1, str2, str3)

如果50是每个字符数组的大小。存储\0字符需要最后一个字符。

此外,检查fopen()的返回值以查看文件是否已成功打开。它会在出错时返回NULL

例如,

if( (fp=fopen('input.txt', 'r'))==NULL )
{
    perror("\nError opening file!");
}

正如评论中所建议的那样,请阅读this帖子。

答案 1 :(得分:0)

首先要做的事情是:Why is while ( !feof (file) ) always wrong?

fscanf&的问题朋友是他们将换行符留在输入缓冲区中 对于fscanf的后续调用,这是一个问题,特别是如果你 混合不同的转换说明符。你的方式也有误 陈述了这种格式,后面在答案中有更多内容。如果你想知道如何 在sscanf循环read this中使用while

您应该检查fscanf的返回值,它会告诉您转化次数 完成后如果已达到EOF

int convs;

while((convs = fscanf(fp, "%s %[^,],%s", s1, s2, s3)) && convs != 3 && convs != EOF)
{
    printf("%s %s,%s\n", s1, s2, s3);
    i++;
}

我将参数更改为s1s2s3,因为您原来也是 很久,很难读。这个想法很重要。

fscanf未转换所有三个值以及何时转换时,您将结束循环 fscanf已达到EOF。然而,问题在于它很难 从错误中恢复,因为你不知道它到底发生了什么。有 但是第二个问题,我在答案的下一部分进行了解释。

由于这个原因,用fgets然后阅读整行是远远优越的 用sscanf解析它。如果sscanf无法解析,则可以恢复和使用 其他解析策略(例如使用strtokstrstr等):

char line[1024];

while(fgets(line, sizeof line, fp))
{
    int convs = sscanf(line, "%s %[^,],%s", s1, s2, s3);
    if(convs != 3)
    {
        // error handling
        // return/exit/use another parsing strategy/whatever
    }
}

%s,%s的一个问题是,对于输入"a,b",只有一个字符串 转换:"a,b"。这是因为%s匹配一系列非空白字符和 ,不是空格,因此scanf在找到非空格之前不会停止 字符。这就是我将其更改为"%[^,],%s"以便进行第一次转换的原因 匹配所有内容直到逗号。