fopen 文件并跳过字符
fopen a file and skip character
有没有一种无需系统调用就可以像这样打开文件的简洁方法:
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
并将输出用作文件名。
这一行
snprintf(source, sizeof(source),"%s/ID%*d_LogConfig.csv",cwd);
可能不会产生您认为的结果。
%*d
部分是具有字段宽度的格式说明符,per the POSIX printf()
documentation
A field width, or precision, or both, may be indicated by an
( '*' ). In this case an argument of type int supplies the
field width or precision. Applications shall ensure that arguments
specifying field width, or precision, or both appear in that order
before the argument, if any, to be converted. A negative field width
is taken as a '-' flag followed by a positive field width. A negative
precision is taken as if the precision were omitted. In format strings
containing the "%n$" form of a conversion specification, a field width
or precision may be indicated by the sequence "*m$", where m is a
decimal integer in the range [1,{NL_ARGMAX}] giving the position in
the argument list (after the format argument) of an integer argument
containing the field width or precision, for example:
printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);
所以,这一行
snprintf(source, sizeof(source),"%s/ID%*d_LogConfig.csv",cwd);
预计要传递 两个 个整数参数。因为你没有传递它们,所以你调用了未定义的行为。
看到这个答案:
好的,我使用以下方法解决了 "problem":
(处理 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] = '[=10=]';
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);
}
看来只有这样简单了
感谢大家。
Is there a clean way to open a file like this without system calls
没有。
fopen()
使用系统调用。没有系统调用就不能 'open' 文件。
如果您指的是 system(3)
函数,那么您可能会遇到一些麻烦 - 从性能、可靠性和安全性的角度来看,最好尽可能避免使用它。
如果你想打开 'all files that match the pattern',然后查看 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);
}
打开大量文件并将流视为单个流 'thing'(就像您对 cat
示例所做的那样)并不是一个好主意。
正如@Andrew 所指出的,您必须 小心使用printf()
格式字符串...
您提供了以下内容:%s/ID%*d_LogConfig.csv
。 %
表示格式说明符的开头,因此您给出了以下内容:
%s
- char *
(字符串)参数后跟
%*d
- 类似于 %d
,但 *
表示精度作为 int
参数提供,后跟数字本身。
例如:
printf(">%s< >%*d<\n", "Hello", 5, 3);
将输出:(注意 %d
输出的 5 个字符)
>Hello< > 3<
如果您在 *
之后,则只需在格式字符串中输入 *
。
如果你在 %
之后,那么你需要转义 %
但将 %%
放在格式字符串中。
有没有一种无需系统调用就可以像这样打开文件的简洁方法:
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
并将输出用作文件名。
这一行
snprintf(source, sizeof(source),"%s/ID%*d_LogConfig.csv",cwd);
可能不会产生您认为的结果。
%*d
部分是具有字段宽度的格式说明符,per the POSIX printf()
documentation
A field width, or precision, or both, may be indicated by an ( '*' ). In this case an argument of type int supplies the field width or precision. Applications shall ensure that arguments specifying field width, or precision, or both appear in that order before the argument, if any, to be converted. A negative field width is taken as a '-' flag followed by a positive field width. A negative precision is taken as if the precision were omitted. In format strings containing the "%n$" form of a conversion specification, a field width or precision may be indicated by the sequence "*m$", where m is a decimal integer in the range [1,{NL_ARGMAX}] giving the position in the argument list (after the format argument) of an integer argument containing the field width or precision, for example:
printf("%1$d:%2$.*3$d:%4$.*3$d\n", hour, min, precision, sec);
所以,这一行
snprintf(source, sizeof(source),"%s/ID%*d_LogConfig.csv",cwd);
预计要传递 两个 个整数参数。因为你没有传递它们,所以你调用了未定义的行为。
看到这个答案:
好的,我使用以下方法解决了 "problem": (处理 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] = '[=10=]';
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);
}
看来只有这样简单了
感谢大家。
Is there a clean way to open a file like this without system calls
没有。
fopen()
使用系统调用。没有系统调用就不能 'open' 文件。
如果您指的是 system(3)
函数,那么您可能会遇到一些麻烦 - 从性能、可靠性和安全性的角度来看,最好尽可能避免使用它。
如果你想打开 'all files that match the pattern',然后查看 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);
}
打开大量文件并将流视为单个流 'thing'(就像您对 cat
示例所做的那样)并不是一个好主意。
正如@Andrew 所指出的,您必须 小心使用printf()
格式字符串...
您提供了以下内容:%s/ID%*d_LogConfig.csv
。 %
表示格式说明符的开头,因此您给出了以下内容:
%s
-char *
(字符串)参数后跟%*d
- 类似于%d
,但*
表示精度作为int
参数提供,后跟数字本身。
例如:
printf(">%s< >%*d<\n", "Hello", 5, 3);
将输出:(注意 %d
输出的 5 个字符)
>Hello< > 3<
如果您在 *
之后,则只需在格式字符串中输入 *
。
如果你在 %
之后,那么你需要转义 %
但将 %%
放在格式字符串中。