简单循环中无法预测的行为,以检查是否行&col存在于文件中 [英] Unpredictable behaviour in simple loop to check if line & col exists in file

查看:56
本文介绍了简单循环中无法预测的行为,以检查是否行&col存在于文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是函数的代码,该函数检查为其指定的行和列坐标"对于将指针传递给它的文件是否有效.

Below is the code for a function that checks if the line and column 'co-ordinates' given to it are valid for a file whose pointer is passed to it.

混乱的12小时后,我不知道为什么这样随机.

12 hours of confusion later, I have no idea why this behaves so randomly.

在自己的源文件上运行此命令时,它会在任何大于 10 的列值上引发错误.我假设一些过分热情的编译器优化将 q 计数变量和 chk 变量并置,并且由于'\ n'具有十进制val 10 ,打破了我的循环.

On running this on it own source file, it throws errors at any column value greater than 10. I assumed that some overenthusiastic compiler optimisations are juxtaposing the q count variable and the chk variable, and since '\n' has decimal val 10, breaking my loop.

假设,我尝试使用GCC进行编译(以前我使用的是Apple Clang).同样的问题.

To assumption, I tried compiling with GCC (previously I was using Apple Clang). Same problem.

在每个文件上,它以大于某个 random col值的任何值失败.在一个文件上,该文件为 12 ,在另一个文件上,该文件为 15 ..为什么?

On each file, it fails at any value greater than some random col value. On one file, this was 12, on another, 15.. Why ??

void check_valid(FILE *ffind,long long line,long long col){

    long long unsigned i,q; int f=0; i=0;int chk;q=0; // counter, character holder and control variables
    if(line>=1 && col>=1){ // -ve lines/columns invalid
        while(i<line){
            // tests if line is valid for file
            chk = fgetc(ffind);
            if(chk==EOF){
                f=-1;printf("\nInvalid Line.\n");break; // line invalid if EOF encountered before reaching line count
            }
            else if(chk=='\n')
                i++;    
        }
        if(f==0){
            //if line was valid, checks if the col value is valid.
            rewind(ffind); 
            while(i<line-1){chk=fgetc(ffind);if(chk=='\n')i++;} // brings fptr @ last char of prev. line, so the next char read is 1st char of given line.
            while(q<col){
                chk=fgetc(ffind);
                if(chk==EOF||chk=='\n'){ // if EOF or newline found before reaching col, col is invalid.
                    f=-1;printf("\nInvalid column = %d\n",chk);break;
                }
                else
                    q++;
            }
            if(f==0) printf("\nValid !\n");
        }
}

推荐答案

发布的代码有两个问题.

The posted code has two problems.

  • if(f == 0){/*行有效*/} 在以下 while(i< line-1)循环.因为上一个循环之后的 i == line-1 ,所以第二个 while 被完全跳过,并且读取从文件的开头开始,而不是行 line.

  • if(f==0){ /* line was valid */ } does not reset i = 0 before the following while(i<line-1) loop. Because i == line-1 after the previous loop, the second while gets skipped altogether, and reading proceeds from the beginning of the file, instead of line line.

只有在 if(chk =='\ n')评估为true之前,一行才算完整.如果它没有以 \ n 换行符终止,则跳过文件的最后一行.在最简单的情况下,只有一个(非空)行但没有 \ n 终止符的文件将始终无法通过 check_valid 测试.

A line is not counted as complete until if(chk=='\n') evaluates to true. This skips over the last line in the file if it is not terminated with a \n newline. In the simplest case, a file with just one (non-empty) line but without a \n terminator will always fail the check_valid test.

虽然每个都可以轻松修复,但是更直接的方法是一次通过检查.

While each of those can be easily fixed, a more direct way is to do the checks in a single pass.

while(i < line){
    chk = fgetc(ffind);
    if(chk == EOF){
        printf("\nInvalid %s.\n", (i == line - 1) ? "Column" : "Line"); break;
    }
    else if(chk == '\n'){
        if(i == line - 1){
            printf("\nInvalid Column.\n"); break;
        }
        i++; q = 0;
    }
    else if(i == line - 1 && q == col - 1){
        printf("\nValid Line/Column.\n"); break;
    }
    else
        q++;
}

这篇关于简单循环中无法预测的行为,以检查是否行&amp;col存在于文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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