在我的程序中,我试图从文本文件中每行读取两个值。 它可以很好地与下面的代码配合使用,但是当我面对带有前导零的数字时,会将每个零存储为一个值。
我希望能够阅读例如“ 007” 为普通的“ 7” ,但我仍然希望能够读取“ 0” 作为值。
任何人都可以帮助我改进代码或指出可以改进哪些地方/什么地方?
预先感谢
valuelist.txt
55 009
63 10
12 0
输出
counter: 0 | Value A: 55 Value B: 0
counter: 1 | Value A: 9 Value B: 0
counter: 2 | Value A: 9 Value B: 0
counter: 3 | Value A: 63 Value B: 0
counter: 4 | Value A: 10 Value B: 0
counter: 5 | Value A: 12 Value B: 0
counter: 6 | Value A: 0 Value B: 0
主要
int main(void) {
char name[] = "valuelist.txt";
unsigned int counter = 0;
unsigned int lines = 3;
unsigned int num;
unsigned int numtwo;
FILE* ff = fopen(name,"r");
if(ff == NULL) {
fprintf(stderr, "Error \n");
return -1;
}
char *tempp = (char*) malloc(lines + 1 );
while(fgets(tempp,lines+1,ff) != NULL){
sscanf(tempp,"%u %u",&num, &numtwo);
printf("counter: %u | ",counter);
printf("Value A: %u ",num);
printf("Value B: %u \n",numtwo);
counter++;
}
free(tempp);
tempp = NULL;
return 0;
}
答案 0 :(得分:4)
在更新的代码和数据中,问题当然是lines
的值对于您的使用而言太小了。您正在使用它来度量tempp
缓冲区所需的空间,但这需要最大行 width (加上一个用于换行,另一个用于终止符)。取而代之的是给它一个 count 行,以及一个只有几行的文件。因此,fgets()
使您在多个呼叫中的通话中断。
您确实可以预扫描文件以找到合适的宽度,然后分配足够的宽度,但是使用fgets
而不是fscanf
会给您带来很多麻烦。对于许多问题,确实有理由偏向于此,但您的问题看起来并不像其中之一。通过执行以下操作,您可以节省大量麻烦和代码:
unsigned num, numtwo;
while (fscanf(ff, "%u%u", &num, &numtwo) == 2) {
// update counter, print results, etc...
}
答案 1 :(得分:2)
您没有分配足够的空间来读取每一行。您正在使用行数作为行长,但是它们并不相同。
您为lines + 1
分配了4个字节(ttemp
),用于在一行中读取。但是,文本的第一行中有6个字符。因此,对fgets
的第一次调用仅读取前3个字节,即"55 "
。这就是sscanf
所解析的内容。下次调用将获取接下来的3个字节,即"09\n"
,并在换行符处停止读取,因此仅解析第一个数字。
由于您在循环中使用fgets
来读取行并打印内容,因此实际上不需要知道有多少行。但是,您确实需要知道一行的最大长度。由于您正在读取两个十进制整数,因此30个字节应该足以读取整行。因此,请使用该大小的固定缓冲区:
char tempp[30];
while(fgets(tempp,sizeof(tempp),ff) != NULL){
...
答案 2 :(得分:0)
您的基本问题是您的lines
变量。它太小了。 (应该是“行大小”吗?)
我建议您摆脱lines
变量,tempp
变量和malloc
的调用。声明一个数组
char line[1000];
1000个字符对于任何可以想象的输入都应该足够长。然后你的循环就可以了
while(fgets(line, sizeof(line), ff) != NULL) { ...
其余的代码看起来还不错。进行此更改后,您应该不再遇到数字怪异分解的问题。