0

ここで解決された問題: 大きな txt ファイルの先頭から fgetc が開始されない

私は c で作業していますが、fgetc がファイルの先頭から文字を取得していません。の後にファイル内のどこかでランダムに開始しているようです\n。この関数の目的は、配列 productsPrinted を変更することです。「More Data Needed」または「Hidden non-listed」が発生した場合、配列の位置、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

計算はコンピュータに任せましょう。文字列を適切に null で終了していません。固定文字列(mdnおよびhdl

このサンプル データを考えると:

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

関数の先頭でファイル ポインタを巻き戻してみてください。

 rewind(category);

ほとんどの場合、別の関数が同じファイルから読み取っています。これで問題が解決する場合は、同じファイルから読み取っている他の関数 (またはこの関数への以前の呼び出し) を見つけ、ポインターを巻き戻しても他の何かが壊れないようにすることをお勧めします。

編集:

念のために言っておきますが、2 つの代入を 2 つの異なるステートメントに変更することもできます。この投稿に基づいて、問題はその行のコンパイラの最適化によって引き起こされる可能性があります。標準で確認していませんが、最良の回答によると、c および c++ での動作は未定義である可能性があるため、奇妙な結果になります。幸運を

于 2013-11-24T01:24:04.003 に答える
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 に答える