我有一个输入文本文件,看起来像这样:
markers.id
我希望能够分别阅读每一行并区分它们。例如,对于第一行,我想将import firebase from '@firebase/app'
import '@firebase/auth';
import '@firebase/database';
import '@firebase/storage';
存储在一个变量中作为1(1.230000e+00)
2(1.230000e+00)
(1.230000e+00 1.230000e+00)
3(1.230000e+00)
(1.230000e+00 1.230000e+00)
.
.
.
,而我想将100
存储在另一个变量中,作为int
。这是我尝试过的:
1.230000e+00
这适用于第一行。但是我该如何遍历所有行,并使用以下命令读取第三行:
double
为了提供上下文,在阅读每一行之后,我将进行一些处理,然后阅读下一行。根据行的格式,我将执行不同类型的处理。
感谢您的帮助!谢谢!
答案 0 :(得分:2)
fscanf (3)几乎不可用。很难区分I / O错误和解析错误。这就是为什么使用 fgets (3)阅读每一行,然后使用 sscanf (3)进行扫描的原因。
由于 sscanf 返回已解析的元素数,因此您可以使用它来确定扫描是否按预期进行。无需窥视输入:如果您达到了预期,就完成了,否则尝试以其他方式进行扫描。这是一个工作示例:
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
int
main( int argc, char *argv[] ) {
if( argc < 2 ) {
errx(EXIT_FAILURE, "syntax: %s filename", argv[0]);
}
FILE *input = fopen(argv[1], "r");
if( !input ) {
err(EXIT_FAILURE, "could not open '%s'", argv[0]);
}
static char line[128];
int n;
while( fgets(line, sizeof(line), input) != NULL ) {
double d1, d2;
int quantum;
if( 2 == sscanf(line, "%d(%lf)", &quantum, &d1) ) {
printf( "ok: %d\t%7.2f\n", 100 * quantum, d1 );
} else if( 2 == sscanf(line, "(%lf %lf)", &d1, &d2) ) {
printf( "ok: %7.2f\t%7.2f\n", d1, d2 );
} else {
printf( ">>> %s\n", line );
}
}
if( !feof(input) ) {
err(EXIT_FAILURE, "error reading %s", argv[1]);
}
return EXIT_SUCCESS;
}
如果您发现其他模式,则可以轻松添加它们。请注意,当 fgets 失败时,仅当我们到达文件末尾时,程序才会返回成功。
答案 1 :(得分:0)
如评论中所述,您可以阅读整行,然后确定该行的格式并相应地解析该行。以下代码可以满足您的需求。但是,有价值的代码可能会更可靠地解释每行的格式。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char *GetStringNoBeginWhitespace( char *str )
{
static const char whitespace[] = " \f\n\r\t\v";
return(str + strspn(str, whitespace));
}
int main(int argc, char *argv[])
{
char *line = NULL;
FILE *fp;
char buffer[255];
int i;
double d,d1;
fp = fopen("data.txt", "r");
while(fgets(buffer, 255, fp))
{
buffer[strlen(buffer)-1] = 0x00;
line = GetStringNoBeginWhitespace( buffer );
if( line )
{
fputs(line, stdout);
if( isdigit((int)line[0] ))
{
printf("\tFormat is x(.......)\n");
if( sscanf(line,"%d(%le)\n", &i, &d) == 2 )
{
printf(" %d %le\n", i, d);
}
else
{
printf("\tUnknown format....\n");
}
}
else if( line[0] == '(' )
{
printf("\tFormat is ( ...... ....... )\n");
if( sscanf(line, "(%le %le)\n", &d, &d1) == 2 )
{
printf(" %le %le\n", d, d1);
}
else
{
printf("\tUnknown format....\n");
}
}
else
{
printf("\tUnknown format....\n");
}
}
}
fclose(fp);
return(0);
}
输出:
jnorton@ubuntu:~/source$ ./a.out 1(1.230000e+00) Format is x(.......) 1 1.230000e+00 2(1.230000e+00) Format is x(.......) 2 1.230000e+00 (1.230000e+00 1.230000e+00) Format is ( ...... ....... ) 1.230000e+00 1.230000e+00 3(1.230000e+00) Format is x(.......) 3 1.230000e+00 (1.230000e+00 1.230000e+00) Format is ( ...... ....... ) 1.230000e+00 1.230000e+00
data.txt文件:
1(1.230000e+00) 2(1.230000e+00) (1.230000e+00 1.230000e+00) 3(1.230000e+00) (1.230000e+00 1.230000e+00)
答案 2 :(得分:0)
如果生成文件,请为行长添加固定大小的前缀。例如。 name = forms.CharField(required=True, max_length=100, widget=forms.TextInput(attrs={'placeholder': 'Enter Name *'}), label=False)
。然后使用016:1(1.230000e+00)\n
读取4个字节,使用fread
将字符串转换为int并读取其余行(长度包括strtol
)。最后用\n
拆分值。