我正在尝试使用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 ,,
,
请帮助!!!
答案 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++;
}
我将参数更改为s1
,s2
和s3
,因为您原来也是
很久,很难读。这个想法很重要。
在fscanf
未转换所有三个值以及何时转换时,您将结束循环
fscanf
已达到EOF
。然而,问题在于它很难
从错误中恢复,因为你不知道它到底发生了什么。有
但是第二个问题,我在答案的下一部分进行了解释。
由于这个原因,用fgets
然后阅读整行是远远优越的
用sscanf
解析它。如果sscanf
无法解析,则可以恢复和使用
其他解析策略(例如使用strtok
或strstr
等):
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"
以便进行第一次转换的原因
匹配所有内容直到逗号。