C,从文件读取时出现奇怪的数值错误 [英] C, strange numerical error while reading from file

查看:101
本文介绍了C,从文件读取时出现奇怪的数值错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了两个函数,它们从.txt文档中读取带有以下内容的行. 贷款数"仅写一次.

Ive written two functions that read lines from a .txt document with posts like the one below. "Number of loans" is only written once.

Number of loans: 1
Loan number:      1
	Sum:          200.000000
	year:         2011
	Interest:     20.000000
	Installment:  1000.000000
	Payed off:    2012
	Description:  12  



该程序读取的内容:



What the program reads:

Loan number:      1
	Sum:          200.000000
	year:         2011000000
	Interest:     20.000000
	Installment:  1000.000000
	Payed off:    
	Description:  12  



已付清"无效,因为它是根据年"值计算的

我写的代码是:



''Payed off'' doesnt work because it''s calculated based on the ''year'' value

The code i have written is:

void readFile( int * nLoans, loan ** memory, FILE * streamPointer ){
    int i, k, d;
    char buf[MAXLINELENGTH+1];

    *nLoans = readLine( STARTNUMBEROFLOANES, MAXLINELENGTH, streamPointer );
    (*memory) = calloc(*nLoans, sizeof(loan));

    for( i = 0; i < *nLoans; i++ ){
	// loanID
		(*memory)[i].loanID = (int)readLine( STARTLOANID, MAXLINELENGTH, streamPointer );
	// values
        (*memory)[i].sum = readLine( STARTOFVALUES, MAXLINELENGTH, streamPointer );
        (*memory)[i].year = (int)readLine( STARTOFVALUES, MAXLINELENGTH, streamPointer );
        (*memory)[i].interest = readLine( STARTOFVALUES, MAXLINELENGTH, streamPointer );
        (*memory)[i].installment =  readLine( STARTOFVALUES, MAXLINELENGTH, streamPointer );
	// yearPayedOff
        fgets( buf, MAXLINELENGTH, streamPointer);
        d = strlen(buf);
        for( k = 0; k < (d - 1 - STARTOFVALUES ); k++ ){
            ((*memory)[i].yearPayedOff)[k] = buf[k + STARTOFVALUES];
        }
        ((*memory)[i].yearPayedOff)[d] = '\0';
	// description
        fgets( buf, MAXLINELENGTH, streamPointer );
        d = strlen(buf);
        for( k = 0; k < (d - STARTOFVALUES - 1) ; k++ ){
            ((*memory)[i].description)[k] = buf[k+ STARTOFVALUES ];
        }
        ((*memory)[i].description)[d] = '\0';
     // just to loose a line
        fgets( buf, 2, streamPointer );
    }
}



和:



and:

double readLine( int indexFirstNumber, int alowedLineLength, FILE * streamPointer ){
    char line[alowedLineLength + 1], numberString[ (int)log(MAXALOWEDLOANSUM) ];
    double returnNumber = 0;
    int i = indexFirstNumber;

    fgets( line, (alowedLineLength+1), streamPointer );
printf("\n%s", line);
    while( line[i] != '\n' && line[i] != ' ' && line[i] != '\0'){
        numberString[i-indexFirstNumber] = line[i];
        i++;
    }
    numberString[i] = '\0';
printf("\n%s", numberString);
	if( !(sscanf(numberString, "%lf", &returnNumber) == 1) ){ printf("\nError reading from file\n"); }
    return returnNumber;
}



程序在文件中的值上添加很多零的错误发生在readLine()



The error, that the program adds lots of zeros to the value in the file, occurs between the two printf() statements in readLine()

推荐答案

中的两个printf()语句之间.该行(已付清")用足够的空白填充,以使您到达*将*的数字所在的列.如果该行被截断为只有很长的一段以包含已付清",则您的索引"i"指向垃圾(又称统一废话).

PS,在第[i]行上使用_atoi()并完成所有字符处理会更容易吗?
This all assumes that the line ("Payed Out") is padded with enough blanks to get you to the column where the number *would have been*. If the line is truncated to be just long enouh to contain "Payed Out", then your index "i" is pointing to garbage (aka, unitialized crap).

PS, would it just be easier to use _atoi() on line[i] and be done with all that character fondling?


你好elroi92,

您的readLine函数在多个方面都容易受到攻击.
由于您不检查行的标签,因此我不会依赖任何文本位置,而是搜索``:''然后从那里扫描,例如(未经编译或测试):

Hello elroi92,

your readLine function is vulnerable on several aspects.
Since you do not check the lable of the lines, I would would not rely on any text position, but rather search for the '':'' and then scan from there, e.g. (not compiled nor tested):

double readLine(FILE *fp)
{
   char line[MAXLINELEN];
   if (fgets(line, MAXLINELEN, fp))
   {
      line[MAXLINELEN-1] = '\0';
      const char *sep = ":";
      char *pos;
      if (strtok_r(line, sep, &pos))
      {
         char *val = strtok_r(line, sep, &pos);
         if (val)
         {
            double d;
            if (sscanf("%lf", val, &d) == 1) return d;
         }
      }
   }
   return 0.0;
}



这样可以解决您的问题吗?

干杯

Andi



Does that solve your problem?

Cheers

Andi


感谢dreamincode中的一个叫r.stiltskin的人.

问题中发布的代码存在两个主要问题.

1:将"\ 0"添加到错误的位置
Thanks to a guy called r.stiltskin at dreamincode.

There are two main problems with the code as posted in the question.

1: the ''\0'' is added at the wrong place
numberString[i] = ''\0'';


应该是:


it should be:

numberString[i - indexFirstNumber] = ''\0'';



2:numberString应为:



2: numberString should be:

numberString[ (int)log10(MAXALOWEDLOANSUM) + 8]


而不是:


and not:

numberString[ (int)log(MAXALOWEDLOANSUM) ]


因为math.h函数日志实际上是ln,并且如果MAXALOWEDLOANSUM等于1 000 000,则它仍只会返回6,没有小数或小数点的余地.

我想可以使用此线程中描述的一种技术来改进功能.


Because the math.h function log is actually ln, and if MAXALOWEDLOANSUM equals something like 1 000 000 it still would only return 6, with no room for decimals or the decimal sign.

I guess the functionality could be improved with one of the tecniques described in this thread.


这篇关于C,从文件读取时出现奇怪的数值错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆