问题解决了: fgetc not starting at 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++;
}
}
}
答案 0 :(得分: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
答案 1 :(得分:0)
也许您可以尝试在函数开头重绕文件指针。
rewind(category);
很可能另一个功能是从同一个文件读取。如果这解决了你的问题,最好找到哪个其他函数(或之前对这个函数的调用)是从同一个文件中读取的,并确保重写指针不会破坏别的东西。
编辑:
而且可以肯定的是,也许您可以将双重赋值更改为两个不同的语句。基于此post,您的问题可能也是由该行的编译器优化引起的。我没有检查标准,但根据最佳答案,c和c ++中的行为可能是未定义的,因此你的结果很奇怪。祝你好运
答案 2 :(得分: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
设置文件位置指示器。
您可以使用调试器来查看这些变量,以了解为什么存在随机值。我认为调试比跟踪输出更有效。