im试图从c。
中的文本文件读取固定大小寄存器寄存器的结构如下:
00030REGIST X1Y005.0
- 整数的5个字符
- 字符串(带空格(的10个字符
- 浮点的5个字符
当我尝试阅读寄存器时,我会得到以下结果:
00030REGIST X1Y005.00.00000
我在字符串末尾获得0.00000
#include <stdio.h>
#include <stdlib.h>
int main () {
int id;
float price;
char desc[11];
FILE * data_file;
//Reading from file
if(!(data_file = fopen("./products.txt","r"))){
printf("nError reading filen");
exit(2);
}
// The value of the register is 00030REGIST X1Y005.0
// But i get 00030REGIST X1Y005.00.00000
while (fscanf(data_file,"%05d %[^n]10s %05f", &id, desc, &price) != EOF) {
printf("%05d%s%05fn",id , desc, price);
}
fclose(data_file);
return(0);
}
编辑:我将程序更改为读取10个字符串字符,其中包括数字。
格式指示符%[^n]10s
是%s
和%[]
的奇怪混合物。我建议以下内容,这里只是一个示例的单个字符串,为了清楚起见,newlines添加到输出中。
#include <stdio.h>
int main(void)
{
int id;
float price;
char desc[11];
char input[] = "00030REGIST X1Y005.0";
int res = sscanf(input, "%d%10[^n]%f", &id, desc, &price);
if(res == 3) {
printf("%05dn%sn%05fn",id , desc, price);
}
}
程序输出:
00030登记X1Y5.000000
你有:
while (fscanf(data_file,"%05d %[^n]10s %05f", &id, desc, &price) != EOF)
您可能需要:
while (fscanf(data_file,"%5d %40[^n0-9] %5f", &id, desc, &price) == 3)
40
基于desc
的大小(您在格式字符串中指定一个比在数组中声明的长度少(。请注意,扫描集%[…]
是单独转换。您版本中的10s
正在寻找特定字符1
,0
和s
(这将失败 - 下一个字符将是新线或文件结束,因为您没有为扫描集指定大小(。测试应适用于预期的转化次数;其他任何东西都是某种错误。
如果寄存器名称可以包含数字,则您的软管是因为REGISTER XVY
是12个字符来计算该空间(这与您的说法矛盾的是寄存器名称最多可达10个字符(。在%12[^n0-9]
中指定任何较小的值都不会转换该名称和以下数字,因为它将在输入中留下非数字字符。
如果您必须具有寄存器名称中的数字,则必须采用其他策略。您会读取该行,然后剥离前5位数字并将其转换,剥离尾随的5位数字并将其转换为转换,并将其剩下的内容作为寄存器名称,可能会剥离领先和落后空白。