我需要从下往上读取文件中列出的数字。我应该如何使用C语言实现?
文件格式如下:
4.32
5.32
1.234
0.123
9.3
6.56
8.77
例如,我想读取最后三个数字。它们必须是 float
类型。8.77
6.56
9.3
附注:实际上我需要一种使用fseek等操作文件指针位置的解决方案。
我需要从下往上读取文件中列出的数字。我应该如何使用C语言实现?
文件格式如下:
4.32
5.32
1.234
0.123
9.3
6.56
8.77
例如,我想读取最后三个数字。它们必须是 float
类型。8.77
6.56
9.3
附注:实际上我需要一种使用fseek等操作文件指针位置的解决方案。
fseek
(带有 SEEK_END
)和 fread
读取文件的最后1024个字节左右,将指针设置为块的末尾,并逆向分析它。这将非常有效,但比前一个建议还有更多的头疼角落。(如果文件的最后三行合计超过1024个字节,您应该做什么?)fgets
和 strtod
。不要使用 atof
或 scanf
,因为 atof
不会告诉您有关语法错误的信息,而 scanf
在溢出时触发未定义行为。顺带提一下,如果你有shell实用程序tac
(这是GNUism),最简单的选择是编写处理标准输入中前三个数字的程序,然后作为tac < input.file | ./a.out
调用它。 浏览代码让我相信,tac
实现了我的“第三种方法”,加入了一些额外的巧妙。
scanf()
的未定义行为吗?或者提供一个相关链接?我尝试在SO和Google上搜索,但没有找到任何信息。 - user12205tac
?不是tail -n 3
。 - Kijewski显然的做法是将它们全部读取,放入一个数组中,然后获取最后三个。
float numbers[3];
char line[100]; // Make it large enough
int = 0;
char* end;
for ( ; ; ++i )
{
i %= 3; // Make it modulo 3.
if ( fgets(line, 100, stdin) == NULL )
{
// No more input.
break;
}
float n = strtof(line, &end);
if ( line == end )
{
// Problem converting the string to a float.
// Deal with error
break;
}
if ( errno == ERANGE )
{
// Problem converting the string to a float within range.
// Deal with error
break;
}
numbers[i] = n;
}
numbers[i]
、numbers[(i+2)%3]
和 numbes[(i+1)%3]
。scanf
进行任何操作。 - zwolscanf
和 %s
存在的危险。您有没有理由相信使用 scanf
和 %f
也存在危险? - R SahuFILE* fp = fopen(..., "r");
fseek(fp, 0, SEEK_END);
int l = X, ofs = 1;
while (l && fseek(fp, ofs++, SEEK_END) == 0) {
if (fgetc(fp) == '\n' && ofs > 2) l--;
}
float numbers[X];
for(int p = 0; p < X; p++) fscanf(fp, "%f", &numbers[p];
我用以下代码解决了我的问题。我读取了文件的后半部分。
FILE *fp = fopen("sample.txt","r");
if( fp == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
int size=0;
char ch;
//Count lines of file
while(( ch = fgetc(fp) ) != EOF )
{
if (ch=='\n') { size++; }
}
int i;
float value;
//Move the pointer to the end of the file and calculate the size of the file.
fseek(fp, 0, SEEK_END);
int size_of_file = ftell(fp);
for (i=1; i<=size/2; i++)
{
//Set pointer to previous line for each i value.
fseek(fp, (size_of_file-1)-i*5, SEEK_SET);
fscanf(fp, "%f", &value);
}