fopen文件并跳过字符

时间:2017-03-16 12:28:08

标签: c printf fopen

有没有一种干净的方法可以在没有系统调用的情况下打开这样的文件:

ID*_LogConfig.csv

我尝试了以下但是没有用。

/*Read setup file*/
getcwd(cwd, sizeof(cwd));
snprintf(source, sizeof(source),"%s/ID%*d_LogConfig.csv",cwd);
if( NULL == (input = fopen(source,"r")))
{
    snprintf(errbuffer,sizeof(errbuffer), "Could not open file %s - check existence/rights\n", source);
    exitHandler(1, errbuffer);
}

输出:

/mnt/dataflash/canfilter.d/ID*_LogConfig.csv not found

但是,例如cat /mnt/dataflash/canfilter.d/ID*_LogConfig.csv它显示文件内容。

我的妥协解决方案是系统调用ll ID*_LogConfig.csv并使用输出作为文件名。

3 个答案:

答案 0 :(得分:2)

这一行

var listOfViewComponents = Assembly
                            .GetEntryAssembly()
                            .GetTypes()
                            .Where(x => x.GetTypeInfo().BaseType == typeof(ViewComponent));

可能不会产生你认为它的作用。

snprintf(source, sizeof(source),"%s/ID%*d_LogConfig.csv",cwd); 部分是一个格式说明符,其字段宽度为per the POSIX printf() documentation

  

字段宽度或精度或两者可以用a表示    ('*')。在这种情况下,int类型的参数提供   字段宽度或精度。申请应确保论证   指定字段宽度或精度,或两者都按该顺序显示   在论证之前,如果有的话,要转换。负字段宽度   被视为' - '标志,后跟正字段宽度。否定的   精度被视为精度被省略。在格式字符串中   包含转换规范的“%n $”形式,字段宽度   或精度可由序列“* m $”表示,其中m为a   给出位置的[1,{NL_ARGMAX}]范围内的十进制整数   整数参数的参数列表(格式参数之后)   包含字段宽度或精度,例如:

%*d

所以,这一行

printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);

要求传递两个更多的整数参数。由于您未传递它们,因此您将调用未定义的行为。

请参阅此答案:https://stackoverflow.com/a/19897395/4756299

答案 1 :(得分:0)

  

是否有一种干净的方法可以在没有系统调用的情况下打开这样的文件

没有。 fopen()使用系统调用。没有系统调用,您无法“打开”文件。

如果您指的是system(3)函数,那么您可能会遇到一些痛苦 - 从性能,可靠性和安全性的角度来看,最好尽可能避免使用它。

如果要打开“与模式匹配的所有文件”,请查看glob(3),这可能是您的shell用于处理此类通配符的内容。 您需要遍历每个生成的路径,并在每个路径上调用fopen()fread()fclose()

glob(3)的使用示例:

#include <stdio.h>
#include <glob.h>

void main(void) {
    int ret;
    int i;
    glob_t glob_info;

    ret = glob("*.csv", 0, NULL, &glob_info);
    if (ret != 0)
    {
        fprintf(stderr, "glob() failed: %d\n", ret);
        return;
    }

    for (i = 0; i < glob_info.gl_pathc; i++) {
        printf("%d: %s\n", i, glob_info.gl_pathv[i]);
    }

    globfree(&glob_info);
}

打开大量文件并将流视为单个“事物”(正如您对cat示例所做的那样)并不是一个好主意。

正如@Andrew指出的那样,必须小心使用printf()格式字符串...... 您提供了以下内容:%s/ID%*d_LogConfig.csv%表示格式说明符的开头,因此您给出了以下内容:

  • %s - char *(字符串)参数如下
  • %*d - 与%d类似,但*表示精确度以int参数的形式提供,后跟数字本身。

例如:

printf(">%s< >%*d<\n", "Hello", 5, 3);

将输出:(注意%d输出的5个字符)

>Hello< >    3<

如果您在*之后,则只需在格式字符串中添加*即可。 如果您在%之后,则需要转义%,但将%%放在格式字符串中。

答案 2 :(得分:-2)

好的,我解决了&#34;问题&#34;使用以下内容: (处理ls -t的输出并使用最新的文件作为配置文件)

/*Search for config-file*/
FILE  *file_config;
file_config = popen("ls -t ID*_LogConfig.csv","r");
if (file_config == NULL)  {
    exitHandler(1, "Error opening date pipe.");
}   
fgets(configfile, sizeof(configfile), file_config);
if (strlen(configfile) > 0)
    configfile[strlen(configfile)-1] = '\0';
else {
    exitHandler(1, "Could not find a ID*_LogConfig.csv\n");
}   
getcwd(cwd, sizeof(cwd));
snprintf(source, sizeof(source),"%s/%s",cwd,configfile);

/*Read setup file*/
if( NULL == (input = fopen(source,"r")))
{   
    snprintf(errbuffer,sizeof(errbuffer), "Could not open file |%s| - check existence/rights\n", source);
    exitHandler(1, errbuffer);
}   

这似乎是唯一简单的方法。

感谢所有人。