我实际上是新手,所以我在学习时遇到了一个错误,实际上我正在尝试从文件fscanf
,然后将其显示在屏幕上,一切正常,直到我在文件中添加带空格的书名为止。它显示book.id
很好,但仅显示该书的名字,其后的整数变为0。
样本输出:
我的功能:
void display_unsorted(FILE *fptr){
int x;
int lines_num=how_many_lines_in_file(fptr);
fptr=fopen("books.dat","r");
if(fptr==NULL){
printf("this file is not open");}
for(i=0;i<lines_num;i++){
fscanf(fptr,"%d\t%s\t%d\n",&books[i].id,books[i].name,&books[i].quantity);
}
for(x=0;x<lines_num;x++){
printf("%d\t%s\t%d\n",books[x].id,books[x].name,books[x].quantity);
}
fclose(fptr);
}
关于:
fscanf(fptr,"%d\t%s\t%d\n",&books[i].id,books[i].name,&books[i].quantity);
建议:
fscanf( fptr,"%d %s %d",
&books[i].id,
books[i].name,
&books[i].quantity );
因为格式字符串中的spaces
将吸收/舍弃输入中的white space
。括号内和逗号后的空格使代码更具可读性
但是,如果书名中包含空格,则最好将整行读入内存缓冲区,然后使用strtok()
使用逗号作为分隔符来提取连续的字段,类似于:
int i = 0;
char buffer[1024];
while( i<lines_num && fgets( buffer, sizeof buffer, fptr ) )
{
char *token = strtok( buffer, ",\t\n" );
if( token )
{
books[i].id = atoi( token );
token = strtok( NULL, ",\t\n" );
if( token )
{
strcpy( books[i].name, token );
token = strtok( NULL, ",\t\n" );
if( token )
{
books[i].quantity = atoi( token );
}
}
}
i++;
}
注意:strtok()
将跳过没有前导数据字符的字符定界符。
注意:如果输入文件中的任何行格式错误,例如没有足够的字段,则此代码可能会失败。
[fscanf
当找到空白时将停止读取,您可以使用以下方法来覆盖此行为:
fscanf(fptr,"%d %99[^0-9] %d\n", &books[i].id, books[i].name, &books[i].quantity);
^^^^^^^^^
翻译,最多读取99个字符的字符串,找到任何数字(即0到9的字符)时将停止读取。
我删除了\t
,这是没有必要的,即使文件包含它们,空格也足够。
请注意,这是针对books[i].name
容器的,最大大小为100个字符,即99个字符加上空终止符。
还请注意,如果字符串中包含数字,则此功能将无法正常工作。