fscanf help:如何检查格式

时间:2013-04-13 07:02:17

标签: c string buffer scanf

所以当前函数应该看到存储在两个英镑符号之间的任何东西(#abc#应该给回abc),但是如果我想错误检查以查看是否有丢失的英镑符号,或者英镑符号之间没有任何内容,或者两个英镑符号之间的字符串长度大于一定数量的字符,我是否使用fscanf函数来做到这一点?

这是fscanf代码的样子:

if (fscanf(fp, " %c%[^#]%c", &start, buffer, &end) == 3) {
    return strdup(buffer);      
} else { 
    return NULL; 

}

3 个答案:

答案 0 :(得分:1)

  

我是否使用fscanf函数来做到这一点?

不,你没有。使用scanf()系列函数很少是一个好主意。

char buf[0x1000];

// expect leading `#'
int ch = fgetc(fp);
if (ch != '#') {
    puts("Error, missing # at beginning of input");
    exit(-1);
}

// read until terminating `#' or until the buffer is exhausted
char *p = buf;
while ((ch = fgetc(fp)) != '#' && p - buf < sizeof(buf)) {
    *p++ = ch;
}

// expect terminating `#'
if (ch != '#') {
    puts("Error, missing # at end of input");
    exit(-1);
}

答案 1 :(得分:1)

如果你需要处理零字符的情况,那么fscanf()可能不是正确的工具。有一个合理的论点,fscanf()很少是正确的工具;您可以使用fgets()sscanf()做得更好。

在这种情况下,我会收集行,直到有一行不是空白(因为那是fscanf()所做的),然后使用#搜索strchr()符号:< / p>

char line[4096];
while (fgets(line, sizeof(line), fp) != 0)
{
    if (strspn(line, " \t\n") == strlen(line))
        continue;
    char *hash1 = strchr(line, '#');
    if (hash1 == 0)
        ...error no hashes...
    else
    {
        char *hash2 = strchr(hash1+1, '#');
        if (hash2 == 0)
            ...second hash is missing...
        if (hash2 - hash1 > MAX_PERMITTED_STRING_LEN)
            ...too long a string...
        *hash2 = '\0';
        char *res = strdup(hash1);
    }
}

答案 2 :(得分:0)

使用Scanf()我显示了我的想法,可能对您有所帮助

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 128
int main(int argc, char *argv[]){
    char h1[MAX]={0},
         h2[MAX]={0},
         buff[MAX] = {0};
    printf("\nEnter String: ");
    scanf("%[#]%[^#\n]%[#]",h1,buff, h2);

    if( (strlen(h1) == 0) || (strlen(buff) == 0) || (strlen(h2) == 0) )
        printf("\n Wrong input ");
    else
        printf("\n h1= %s \n buff= %s \n h2= %s",h1,buff,h2);

    printf("\n");
    return 1;
}

运行:

:~$ gcc s.c
:~$ ./a.out 
Enter String: #
 Wrong input 
:~$ ./a.out 
Enter String: #abc
 Wrong input 
:~$ ./a.out 
Enter String: #abc#
 h1= # 
 buff= abc 
 h2= #
:~$ ./a.out 
Enter String: abc#
 Wrong input 
:~$ 

这是你想要的东西吗?我不是说什么是好的,只是从我的代码中得到一个想法。

你可以添加@Cnicutar的想法,他发布了一个评论你的问题进行长度验证,否则在if子句中你可以检查buff长度,如:strlen(buff) > MIN_LENGHT_REQ

编辑:感谢@Jonathan Leffler!

我刚刚用MAX更改了h1 [],h2,buff的定义,并更新了相同的代码来解析'###abc###',现在除了上面的运行之外,它还支持以下几种运行:

:~$ ./a.out 
Enter String: ####aaa
 Wrong input 
:~$ ./a.out 
Enter String: abs####
 Wrong input 
:~$ ./a.out 
Enter String: ###abc###
 h1= ### 
 buff= abc 
 h2= ###
:~$ ./a.out 
Enter String: abc
 Wrong input 
:~$ ./a.out 
Enter String: ###
 Wrong input 
:~$ 

仍然只是我的想法,也只是自己测试,并尝试用Jonathan Leffler的答案解决问题。

这就是我所说的想法,我正在努力改进它,会在我改进时更新我的​​答案,我相信必须有一些技巧