我如何检查C中的每一行文件?

时间:2014-05-30 18:25:47

标签: c

我是C的新手 我被要求检查文本文件输入的格式是否正确! 该文件应该有这样的行:

1-float
2-('+'/'*'/'-')
3-flaot
4-'='
5-the result of the above operation
6-';'

我读取文件并将每个char放在一个数组中,但不知道下一步该做什么 这是我的代码

#include <stdio.h>
#include <conio.h>
/*Max number of characters to be read/write from file*/
#define MAX_CHAR_FOR_FILE_OPERATION 1000000 



int main()
{

   char *filename = "D:\input.txt";
   FILE *fp;
   char text[MAX_CHAR_FOR_FILE_OPERATION];
   int i;

   fp = fopen(filename, "r");

   if(fp == NULL)
   {
      printf("File Pointer is invalid\n");
      return -1;
   }
   //Ensure array write starts from beginning
   i = 0;

   //Read over file contents until either EOF is reached or maximum characters is read and store in character array
   while( (fgets(&text[i++],sizeof(char)+1,fp) != NULL) && (i<MAX_CHAR_FOR_FILE_OPERATION) ) ;

   //Ensure array read starts from beginning


   fclose(fp);



   getche();
   return 0;
}  

2 个答案:

答案 0 :(得分:1)

我能想到的最简单的解决方案是创建一个自动机。这可能是一个包含步骤的枚举,例如:

enum AUTOMATE
{
    FirstFloat = 0,
    FirstSign,
    SecondFloat,
    EqualSign,
    Answer
};

有关如何在此处使用枚举的更多信息:http://msdn.microsoft.com/en-us/library/whbyts4t.aspx

如果已经拥有数组中的所有char,则使用您想要的任何循环遍历整个数组,并检查每个char的整数值。使用此表http://www.asciitable.com/来检查天气,整数值表示数字或符号( - ,+,=等)。通过每个步骤后,告诉您的自动化进一步(+ = 1)。如果你到达目的地,你就验证了它。如果没有,则格式错误。

答案 1 :(得分:0)

这不是100%清楚你想在这里做什么。

如果您只想检查表达式在语法上是否正确,那就是一回事。如果你想检查也是算术正确(即=的RHS上的结果实际上是LHS上算术表达式的结果),那就是另一个。< / p>

在任何一种情况下,都必须解析输入行。有几种方法可以做到这一点。规范,通用和健壮的方法是使用词法分析器对行进行标记,并将标量从词法分析器传递给解析器,这是一种有限状态机,它“知道”你试图解析的语言的语法(在这种情况下是中缀算术表达式)。鉴于你问了这个问题,我们可以假设你还没有得到这种材料。

在您的情况下,您只处理以下形式的简单中缀算术表达式:

NUMBER OPERATOR NUMBER = NUMBER ;

您可以使用scanf()系列函数检查“看起来”与此类似的行,但这是一个脆弱的解决方案:如果您添加另一个术语对于左边的表达,它会破碎;制作正确的格式字符串需要非常谨慎;并且它检查算术正确性。

如果你需要的只是这么简单,你就可以这样做(我省略了文件I / O):

#include <stdio.h>
#include <stdbool.h>

#define OPERATOR_CLASS "[-+/*]"


bool is_a_binary_infix_expression(const char *expr)
{
    int   count;                // Count returned by sscanf()                                                                                      
    float left_opd;             // Left operand                                                                                                    
    char  operator[2] = {'\0'}; // Operator                                                                                                        
    float right_opd;            // Right operand                                                                                                   
    float result;               // Result                                                                                                          
    char  junk;                 // Trailing junk                                                                                                   

    // Format specifier for sscanf():                                                                                                              
    const char *format = "%f %1" OPERATOR_CLASS "%f =%f ; %c";

    // Attempt conversion:                                                                                                                         
    count = sscanf(expr, format, &left_opd, operator, &right_opd, &result, &junk);

    // If exactly 4 conversions succeeded, the expression was good. If fewer,                                                                      
    // the conversion failed prematurely. If 5, there was trailing junk:                                                                           
    return count==4;
}

int main(void) {
    int i;
    int n_lines;
    char *lines[]={
        "1.5+2.2=3.7;",
        "1.5 + 2.2 = 3.7 ; ",
        "a+2.2=3.7;",
        "1.5+2.2=3.7;x",
    };


    n_lines = (int)sizeof(lines)/sizeof(char *);

    for(i=0; i<n_lines; i++) {
        printf("'%s' is %s\n", lines[i], is_a_binary_infix_expression(lines[i]) ? "OK" : "NOT OK");
    }

    return 0;
}

这只检查语法正确性。如果要检查算术正确性,可以在操作数上switch计算正确的结果,并将其与从输入行提取的结果进行比较,但要注意不要陷入直接比较的陷阱与==