2016-11-21 22 views
0

我有一个严酷的时间来实现这一点。我读了一串整数,从那个链中提取它们并将它们放入一个数组中。我想尝试一些新的东西,因为以前用getChar来描述字符的字符,但是现在我找到了处理这个工作的sscanf使用sscanf区分新行和错误

From Doc(sscanf): 成功时,函数返回成功填充的参数列表中的项目数。在匹配失败的情况下,该计数可以匹配预期的项目数量或更少(甚至为零)。 在任何数据可以被成功解释之前输入失败的情况下,返回EOF。

行:char line[] = "100 185 20 11 1000"; // number of int is unknown, it can differ

问题:如何使线的末端和任何错误

EG之间diffrence:char line[] = "100 185 abc(not int) 11 1000";

代码

int main(int argc, char** argv) { 

    char line[] = "100 185 20 11 1000";  
    int arrOfInt[10]; 
    char *data = line; 
    int track, number, index = 0; 

    while ((sscanf(data, " %d%n", &number, &track)) == 1) 
    { 
     arrOfInt[index] = number; 
     data += track; 
     index++; 
    } 
    return 0; 
} 
+1

'而.... == 1' ... emm..why? –

+0

1表示成功 –

+0

是吗?你不应该写_“成功时,函数返回成功填充的参数列表中的项目数。”_? –

回答

2

@BLUEPIXY提到了正确的答案。只是在这里形式化。

如果scanf的返回值是EOF那意味着可以看到EOF。如果是0这意味着发生了一些其他错误,并且通过%n设置的值未定义(例如,输入与指定的格式不匹配)。

只要没有带有混合字母和字母的令牌,如“hey45hey2”,以下方法就可以工作。

#include <stdio.h> 
#include <stdlib.h> 
int main(int argc, char** argv) { 

    char line[] = "100 185 20 11 1000 sdf 342 hey45hey2";  
    int arrOfInt[10]; 
    char *data = line; 
    int track, status = 0, number, index = 0; 

    // read until an EOF is found 
    while ((status = sscanf(data, " %d%n", &number, &track)) != EOF) 
    { 
     // store only if status is non-zero i.e. sscanf has read according to the format specified 
     if(status != 0){ 
      arrOfInt[index] = number; 
      index++; 
     } 
     else 
      track=1; 
     data += track; 
    } 
    // print the array back to check if we read correctly 
    int i; 
    for(i=0;i<index;i++) 
    printf("%d ", arrOfInt[i]); 
    return 0; 
} 

这段代码的输出是:

100 185 20 11 1000 342 45 2 

如果你想排除字符串就像从输出“hey45hey2”,然后使用以下。

#include <stdio.h> 
#include <stdlib.h> 
int main(int argc, char** argv) { 

    char line[] = " egsdfgfd rgege 100 185 20 11 hey45hey2 0d0 00 sddbrsdtbrtsdbrsf 342";  
    int arrOfInt[10]; 
    char *data = line; 
    int track, status = 0, index = 0; 
    char str[100]; // will fail for tokens of length more than 100 

    // read until an EOF is found 
    while ((status = sscanf(data, "%s%n", str, &track)) != EOF) 
    { 
     // store only if status is non-zero 
     if(status != 0){ 
      // check if str is all zeros 
      int num=(int)strtol(str,0,10); 
      char *i = str; 
      if(num == 0){ 
       while(*i){ 
        if(*i != '0') break; 
        i++; 
       } 
      } 
      if(*i == 0 || num != 0){ 
       // if *i is zero, then num is also zero 
       arrOfInt[index] = num; 
       index++; 
      } 
     } 
     else 
      track = 1; 
     data += track; 
    } 
    // print the array back to check if we read correctly 
    int i; 
    for(i=0;i<index;i++) 
    printf("%d ", arrOfInt[i]); 
    return 0; 
} 

输出是100 185 20 11 0 342

+0

这个句柄'“sdf 100 185 20 11 1000 342”'? – alk

+0

@alk请参阅编辑 – Nishant

+0

所以现在实际上你*自己*解析*;) – alk

1

如何区分行结束和任何错误

对不起,这样说,但答案是:Drop sscanf,并自己进行解析。


如果,什么都原因,你需要/想坚持sscanf可以始终做到了“串” sscanf完成后测试,看如果有愈后读取最后一个标记,就像你知道解析的标记数量一样。例如,您可以通过在空白处使用strtok来预先标记字符串来实现此目的,如果您扫描的内容很少,那么您会将字符串指针放在最后一个+ 1标记后面并继续使用sscanf。但这是否理智? ;-)

+0

您的意思是,阅读逐个字符并使用strtod来检查它是否是一个数字 –

+0

是的,要从s“string”中解析出要使用'strto *()'函数家族的强大成员的数字。 @DavidEdgar – alk

1

我实现我真正想要用你的建议去做。只要提到,当我发现不需要的角色时,我必须离开我的循环并显示错误。

代码(可以为别人有用)

int main(int argc, char** argv) { 

    char line[] = "100 185 20 11 1000"; // or "100 185 abc 11 1000"  
    int arrOfInt[10]; 
    char *data = line; 
    int track, number, index = 0; 

    int statutLine; 


    while ((statutLine = sscanf(data, " %d%n", &number, &track)) == 1) 
    { 
     arrOfInt[index] = number; 
     data += track; 
     index++; 
    } 

    if(statutLine == 0){ 
     printf("Line invalide"); 
    } 

    if(statutLine == EOF){ 
     printf("Line valide"); 
    } 

    return 0; 
}