0

问题在这里解决了: fgetc not started at the beginning of large txt file

我在 c 中工作,而 fgetc 没有从文件的开头获取字符。它似乎是在文件中的某个地方随机开始的\n。此函数的目标是修改数组 productsPrinted。如果遇到“需要更多数据”或“隐藏未列出”,则数组中的位置 productsPrinted[newLineCount] 将更改为 0。感谢任何帮助。

更新:它适用于较小的文件,但不能从较大的 617kb 文件的开头开始。

函数调用类别:

findNoPics(image, productsPrinted);
findVisible(visible, productsPrinted);
removeCategories(category, productsPrinted);

fgetc() 的示例输入:

Category\n
Diagnostic & Testing /Scan Tools\n
Diagnostic & Testing /Scan Tools\n
Hidden non listed\n
Diagnostic & Testing /Scan Tools\n
Diagnostic & Testing /Scan Tools\n
Hand Tools/Open Stock\n
Hand Tools/Sockets and Drive Sets\n
More Data Needed\n
Hand Tools/Open Stock\n
Hand Tools/Open Stock\n
Hand Tools/Open Stock\n
Shop Supplies & Equip/Tool Storage\n
Hidden non listed\n
Shop Supplies & Equip/Heaters\n

代码:

void removeCategories(FILE *category, int *prodPrinted){

char more[17] = { '\0' }, hidden[18] = { '\0' };
int newLineCount = 0, i, ch = 'a', fix = 0;

while ((ch = fgetc(category)) != EOF){  //if fgetc is outside while, it works//

    more[15] = hidden[16] = ch;
    printf("%c", ch);

    /*shift char in each list <- one*/
    for (i = 0; i < 17; i++){
        if (i < 17){
            hidden[i] = hidden[i + 1];
        }
        if (i < 16){
            more[i] = more[i + 1];
        }
    }

    if (strcmp(more, "More Data Needed") == 0 || strcmp(hidden, "Hidden non listed") == 0){
        prodPrinted[newLineCount] = 0;
        /*printf("%c", more[0]);*/
    }
    if (ch == '\n'){
        newLineCount++;
    }
} 

}

4

3 回答 3

1

让计算机来计算。你没有正确地终止你的字符串。固定字符串 (mdnhdl已初始化但没有空终止符,因此使用它们的字符串比较未定义。

鉴于此示例数据:

Example 1
More Data Needed
Hidden non listed
Example 2
Keeping lines short.
But as they get longer, the overwrite is worse...or is it?
Hidden More Data Needed in a longer line.
Lines containing "Hidden non listed" are zapped.
Example 3

这个版本的程序:

#include <stdio.h>
#include <string.h>

static
void removeCategories(FILE *category, int *prodPrinted)
{
    char more[17] = { '0' };
    char hidden[18] = { '0' };
    char mdn[17] = { "More Data Needed" };
    char hnl[18] = { "Hidden non listed" };
    int newLineCount = 0, i, ch = '\0';

    do
    {
        /*shift char in each list <- one*/
        for (i = 0; i < 18; i++)
        {
            if (i < 17)
                hidden[i] = hidden[i + 1];
            if (i < 16)
                more[i] = more[i + 1];
        }
        more[15] = hidden[16] = ch = fgetc(category);
        if (ch == EOF)
            break;
        printf("%c", ch);           /*testing here, starts rndmly in file*/
        //printf("<<%c>> ", ch);           /*testing here, starts rndmly in file*/

        //printf("more <<%s>> hidden <<%s>>\n", more, hidden);
        if (strcmp(more, mdn) == 0 || strcmp(hidden, hnl) == 0)
        {
            prodPrinted[newLineCount] = 0;
        }
        if (ch == '\n')
        {
            newLineCount++;
        }
    } while (ch != EOF);
}

int main(void)
{
    int prod[10];
    for (int i = 0; i < 10; i++)
        prod[i] = 37;
    removeCategories(stdin, prod);
    for (int i = 0; i < 10; i++)
        printf("%d: %d\n", i, prod[i]);
    return 0;
}

产生这个输出:

Example 1
More Data Needed
Hidden non listed
Example 2
Keeping lines short.
But as they get longer, the overwrite is worse...or is it?
Hidden More Data Needed in a longer line.
Lines containing "Hidden non listed" are zapped.
Example 3
0: 37
1: 0
2: 0
3: 37
4: 37
5: 37
6: 0
7: 0
8: 37
9: 37
于 2013-11-24T02:35:19.787 回答
0

您可以检查您打开文件的模式,并且您可能会进行一些错误检查以确保您获得了正确的返回值。

这里可以参考man fopen获取哪种模式导致流位置。

   The fopen() function opens the file whose name is the string pointed to
   by path and associates a stream with it.
   The argument mode points to a string beginning with one of the  follow‐
   ing sequences (Additional characters may follow these sequences.):

   r      Open  text  file  for  reading.  The stream is positioned at the
          beginning of the file.

   r+     Open for reading and writing.  The stream is positioned  at  the
          beginning of the file.

   w      Truncate  file  to  zero length or create text file for writing.
          The stream is positioned at the beginning of the file.

   w+     Open for reading and writing.  The file is created  if  it  does
          not  exist, otherwise it is truncated.  The stream is positioned
          at the beginning of the file.

   a      Open for appending (writing at end of file).  The file  is  cre‐
          ated  if it does not exist.  The stream is positioned at the end
          of the file.

   a+     Open for reading and appending (writing at end  of  file).   The
          file is created if it does not exist.  The initial file position
          for reading is at the beginning  of  the  file,  but  output  is
          always appended to the end of the file.

还有一个提示,你操作的文件不能超过2G,否则可能有问题。

并且您可以使用fseek来设置文件位置指示器。

你可以使用调试器来观察这些变量,看看为什么会有随机值。我认为调试比跟踪输出有效。

于 2013-11-24T01:59:13.037 回答
0

也许您可以尝试在函数的开头倒回文件指针。

 rewind(category);

很可能另一个函数正在从同一个文件中读取。如果这解决了您的问题,最好找出哪个其他函数(或之前对该函数的调用)正在从同一文件中读取,并确保倒回指针不会破坏其他内容。

编辑:

并且可以肯定的是,也许您可​​以将双重赋值更改为两个不同的语句。根据这篇文章,您的问题也可能是由该行的编译器优化引起的。我没有检查标准,但根据最佳答案,c 和 c++ 中的行为可能是未定义的,因此你的结果很奇怪。祝你好运

于 2013-11-24T01:24:04.003 回答