使用fprintf和fscanf时出错
我有一个归档文件使用fprintf和fscanf时出错,c,string,windows,printf,scanf,C,String,Windows,Printf,Scanf,我有一个归档文件results.csv,我需要阅读此归档文件的第一行并将其打印在output.txt上。不知怎的,这是打印随机字符后,一切,我无法找出什么是错的 命令:a.c results.csv 第一行: 日期、主队、客队、主队得分、客队得分、锦标赛、城市、国家、中立 output.txt:日期,主队,客队,主队,客队,比赛,城市,国家,中立,(!£,(!£,(!£,(!£,@,(!£,(!£,(!£,),(!£ #include <stdio.h> #include <s
results.csv
,我需要阅读此归档文件的第一行并将其打印在output.txt
上。不知怎的,这是打印随机字符后,一切,我无法找出什么是错的
命令:a.c results.csv
第一行:
日期、主队、客队、主队得分、客队得分、锦标赛、城市、国家、中立
output.txt:日期,主队,客队,主队,客队,比赛,城市,国家,中立,(!£,(!£,(!£,(!£,@,(!£,(!£,(!£,),(!£
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct
{
char *line1;
char *line1a;
char *line1b;
char *team1;
char *team2;
char *reason;
char *city;
char *country;
char *neutral_field;
}data;
void open_input(char *argv[], FILE **input)
{
if((*input=fopen(argv[1], "r")) == NULL)
{
printf("%s not found\n", argv[1]);
exit(1);
}
}
void open_output(char *string, FILE **output)
{
if((*output=fopen(string, "w")) == NULL)
{
printf("%s not found\n", string);
exit(1);
}
}
void alloc_data(data *d, int size)
{
d->line1 = (char*)malloc(4*sizeof(char));
d->team1 = (char*)malloc(9*sizeof(char));
d->team2 = (char*)malloc(9*sizeof(char));
d->line1a = (char*)malloc(10*sizeof(char));
d->line1b = (char*)malloc(10*sizeof(char));
d->reason = (char*)malloc(10*sizeof(char));
d->city = (char*)malloc(4*sizeof(char));
d->country = (char*)malloc(7*sizeof(char));
d->neutral_field = (char*)malloc(7*sizeof(char));
}
void store(data *d, FILE *input, FILE **output)
{
fscanf(input, "%s,%s,%s,%s,%s,%s,%s,%s,%s", d[0].line1, d[0].team1, d[0].team2, d[0].line1a, d[0].line1b, d[0].reason, d[0].city, d[0].country, d[0].neutral_field );
fprintf(*output, "%s,%s,%s,%s,%s,%s,%s,%s,%s\n", d[0].line1, d[0].team1, d[0].team2, d[0].line1a, d[0].line1b, d[0].reason, d[0].city, d[0].country, d[0].neutral_field );
}
int main(int argc, char *argv[])
{
FILE *input;
FILE *output;
char *string = "output.txt";
int size = 1000;
open_input(argv, &input);
open_output(string, &output);
data *d;
d = (data*)malloc(size*sizeof(data));
alloc_data(d, size);
store(d, input, &output);
free(d);
return 0;
}
#包括
#包括
#包括
#包括
类型定义结构
{
字符*line1;
char*line1a;
char*line1b;
char*team1;
char*team2;
原因;
查尔*城市;
char*国家;
字符*中性_字段;
}数据;
无效打开_输入(字符*argv[],文件**输入)
{
if((*input=fopen(argv[1],“r”)==NULL)
{
printf(“%s未找到”\n“,argv[1]);
出口(1);
}
}
无效打开_输出(字符*字符串,文件**输出)
{
if((*output=fopen(字符串,“w”))==NULL)
{
printf(“%s未找到\n”,字符串);
出口(1);
}
}
无效alloc_数据(数据*d,整数大小)
{
d->line1=(char*)malloc(4*sizeof(char));
d->team1=(char*)malloc(9*sizeof(char));
d->team2=(char*)malloc(9*sizeof(char));
d->line1a=(char*)malloc(10*sizeof(char));
d->line1b=(char*)malloc(10*sizeof(char));
d->reason=(char*)malloc(10*sizeof(char));
城市=(char*)malloc(4*sizeof(char));
d->country=(char*)malloc(7*sizeof(char));
d->中性_字段=(字符*)malloc(7*sizeof(字符));
}
无效存储(数据*d,文件*输入,文件**输出)
{
fscanf(输入,“%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%d[0]。行1,d[0]。队1,d[0]。队2,d[0]。行1a,d[0]。行1b,d[0]。原因,d[0]。城市,d[0]。国家,d[0]。中性字段);
fprintf(*输出,“%s,%s,%s,%s,%s,%s,%s,%s\n”,d[0]。第1行,d[0]。第1组,d[0]。第2组,d[0]。第1a行,d[0]。第1b行,d[0]。原因,d[0]。城市,d[0]。国家,d[0]。中性字段);
}
int main(int argc,char*argv[])
{
文件*输入;
文件*输出;
char*string=“output.txt”;
int size=1000;
打开_输入(argv,&input);
打开\u输出(字符串和输出);
数据*d;
d=(数据*)malloc(尺寸*尺寸(数据));
alloc_数据(d,大小);
存储(d、输入和输出);
免费(d);
返回0;
}
您的缓冲区不够大,无法容纳终止的NUL字节。scanf
存储该NUL字节(超出缓冲区),但实际拥有该字节的对象可能会覆盖它,因此,当printf
查找NUL时,它直到很久以后才在内存中找到它
缓冲区溢出是一个比你所看到的更大的问题,谁知道那些你没有腾出空间的NUL字节正在粉碎什么对象?当你读取一个标题拼写稍有不同的数据文件时会发生什么情况?突然之间,你的硬编码分配大小将比现在更加错误。你的缓冲区不是big足以容纳终止的NUL字节。
scanf
存储该NUL字节(超出缓冲区),但实际拥有该字节的对象可能会覆盖它,因此当printf
查找NUL时,直到很久以后在内存中才找到它
缓冲区溢出是一个比您所看到的更大的问题,谁知道那些没有为其留出空间的NUL字节正在粉碎哪些对象?以及当您读取一个标题拼写稍有不同的数据文件时会发生什么情况?突然之间,您的硬编码分配大小将比以前更加错误
fscanf(输入,“%s,%s,%s,%s,%s,%s,%s,%s”,d[0]。行1,d[0]。团队1,…
上面的代码尝试将整行读入到d[0]。line1
会导致缓冲区溢出。team1
,其余将包含未初始化的数据
您必须更改fscanf
,如下所示:
fscanf(input, "%3[^ ,\n\t],%9[^ ,\n\t],...
其中3是4-1,4是d[0]的大小
或者,您可以使用strtok
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void store(FILE *input, FILE *output)
{
char buf[500];
while(fgets(buf, sizeof(buf), input))
{
//strip end-of-line from `buf`
if(strlen(buf))
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
//tokenize with strtok
char *token = strtok(buf, ",");
while(token)
{
fprintf(output, "%s", token);
token = strtok(NULL, ",");
}
fprintf(output, "\n");
}
}
int main(int argc, char *argv[])
{
FILE *input = fopen("input.txt", "r");
FILE *output = fopen("output.txt", "w");
store(input, output);
return 0;
}
此外,对于每个malloc
,应该有一个相应的free
fscanf(输入,“%s,%s,%s,%s,%s,%s,%s,%s”,d[0]。行1,d[0]。团队1,…
上面的代码尝试将整行读入到d[0]。line1
会导致缓冲区溢出。team1
,其余将包含未初始化的数据
您必须更改fscanf
,如下所示:
fscanf(input, "%3[^ ,\n\t],%9[^ ,\n\t],...
其中3是4-1,4是d[0]的大小
或者,您可以使用strtok
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void store(FILE *input, FILE *output)
{
char buf[500];
while(fgets(buf, sizeof(buf), input))
{
//strip end-of-line from `buf`
if(strlen(buf))
if(buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
//tokenize with strtok
char *token = strtok(buf, ",");
while(token)
{
fprintf(output, "%s", token);
token = strtok(NULL, ",");
}
fprintf(output, "\n");
}
}
int main(int argc, char *argv[])
{
FILE *input = fopen("input.txt", "r");
FILE *output = fopen("output.txt", "w");
store(input, output);
return 0;
}
另外,对于每个malloc
都应该有一个相应的免费%c
用于打印char
d[0]。第1行(和其他行)是char*
。你是说scanf for char数组中的%s
?%c
用于单个char。你将要了解为什么f()
太可怕了。使用扫描()读取数据
格式字符串无法通过同一格式字符串可靠地打印。也可以使用%s
打印字符*
,但在这里它可能会失败,因为字符数组没有正确终止。另外,您真的需要文件**输出
在函数存储
中吗?使用文件*输出
有什么问题吗>%c
用于打印char
d[0]。line1
(和其他)是char*
。您的意思是在scanf for char数组中的%s
吗?%c
用于单个字符。您将要了解scanf()
为什么可怕。使用scan()读取数据
格式字符串无法通过同一格式字符串可靠地打印。也可以使用%s
打印字符*
,但在这里它可能会失败,因为字符数组没有正确终止。另外,您真的需要函数存储中的文件**输出
?使用该函数有什么问题吗