2013-01-24 48 views
1

有一个文件a.txt中读取如下:使用的fscanf在项目

1 abc 
2 
3 jkl 

我想读这个文件的每一行作为int和一个字符串,像这样:

fp = fopen("a.txt", "r"); 
while (1) { 
    int num; 
    char str[10]; 
    int ret =fscanf(fp, "%d%s", &num, str); 
    if (EOF == ret) 
     break; 
    else if (2 != ret) 
     continue; 
    // do something with num and str 
} 

但有一个问题,如果a.txt中的一行只包含一个数字,没有字符串(就像第2行),那么上面的代码将被卡在该行。

那么任何方式跳到下一行?

+0

int ** ret = fscanf(“%d%s”,#num,str)**你忘记了在这个调用中引用fp吗?它应该是** int ret = fscanf(fp,“%d%s”,#num,str); ** – zdesam

+0

@zdesam,对不起 – Alcott

+0

你有什么异常? – zdesam

回答

2

做的两个步骤:

  1. 阅读使用fgets()全系列。这假定你可以对你想要支持的行数做一个简单的静态限制,但是情况往往如此。使用sscanf()来检查和解析该行。

这可以解决您碰到的问题,并且对于像这样的问题来说通常是更好的方法。

UPDATE:试图回应您的评论。我看到它的方式是,最简单的方法是始终阅读整行(如上),然后解析出您认为它包含的两个字段:数字和字符串。

如果你这样做与sscanf(),您可以使用返回值要弄清楚它是如何去,像你fscanf()在你的代码的尝试:

const int num_fields = sscanf(line, "%d %s", &num, str); 
if(num_fields == 1) 
    ; /* we got only the number */ 
else if(num_fields == 2) 
    ; /* we got both the number and the string */ 
else 
    ; /* failed to get either */ 

不知道什么时候你不会“需要”字符串;它可能在那里,或者不是。

+0

谢谢。如果我在num之后不需要字符串,我的意思是可以使用这个'fscanf(fp,“%u%* c”,&num);'? – Alcott

+0

那么,我试图通过使用'fscanf'来完成这项工作一枪,但感谢的人;-) – Alcott

1

如果字符串的第一个字符是\r or\n,这将是一个空字符串。你可以使用比较。 fscanf()函数是不适合的,如果把包含空格的(或空行)。在这种情况下,更好地用fgets()

+0

那么,问题是,代码卡在第2行。 – Alcott

1

如何解决“使用的fscanf”:

int后,查找空间(不保存),然后寻找char不在'\n'

int num; 
char str[10]; 
#define ScanInt   "%d" 
#define ScanSpacesDontSave "%*[ ]" 
#define ScanUntilEOL  "%9[^\n]" 

int ret = fscanf(fp, ScanInt ScanSpacesDontSave ScanUntilEOL, &num, str); 
if (EOF == ret) break; 
else if (1 == ret) HandleNum(num); 
else if (2 == ret) HandleNumStr(num, str); 
else HadleMissingNum(); 

ret将2如果东西被扫描到str,否则ret将典型地1.特技上述不以扫描'\n'int之后。因此代码不能在"%d"之后使用"%s"" ",它们都消耗所有(领先的)空白。 下一个fscanf()通过"%d"作为主要空白消费的一部分,呼叫将消耗'\n'

小调:读取fgets(),然后解析缓冲区通常是一个更好的方法,但编码目标可能会排除这一点。

+0

这很整洁,谢谢。 – Alcott