- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在处理的代码涉及读取带有输入的文件,其结构如下:
(spaces)name(spaces) val (whatever) \n
(spaces)name(spaces) val (whatever) \n
(spaces)name(spaces) val (whatever) \n
"name: (name) value: val \n"
a 12
b 33
#c 15
nice 6#9
Line after: a 12
name: a value: 12 :
Line after: b 33
name: b value: 33 :
Line after: # c 15
Line after: nice 6#9
name: nice value: 6 :
Line after:
name: value: 6 : //why is this happening
void readLine(char *filename)
{
FILE *pf;
char name[10000];
char value[20];
pf = fopen(filename, "r");
char line[10000];
if (pf){
while (fgets(line, sizeof(line), pf) != NULL) {
//printf("Line: %s\n",line);
printf("Line after: %s\n",line);
while(true){
int i=0;
char c=line[i]; //parse every char of the line
//assert(c==' ');
int locationS=0; //index in the name
int locationV=0; //index in the value
while((c==' ')&& i<sizeof(line)){
//look for next sequence of chars
++i;
c=line[i];
if(c=='#'){
break;
}
}
if(c=='#'){ break;}
assert(c!=' ');
while (c!=' '&&i<sizeof(line))
{
name[locationS]=c;
locationS++;
//printf("%d",locationS);
++i;
c=line[i];if(c=='#'){
break;
}
}
if(c=='#'){ break;}
assert(c==' ');
while(c==' '&&i<sizeof(line)){
//look for next sequence of chars
++i;
c=line[i];
if(c=='#'){
break;
}
}
if(c=='#'){ break;}
assert(c!=' ');
printf("\n");
while ((c!=' '&& c!='\n')&&i<sizeof(line))
{
value[locationV]=c;
locationV++;
++i;
c=line[i];if(c=='#'){
break;
}
}
printf("name: %s value: %s : \n",name, value);
memset(&name[0], 0, sizeof(name));
memset(&value[0], 0, sizeof(value));
break; //nothing interesting left
}
}
fclose(pf);
}else{
printf("Error in file\n");
exit(EXIT_FAILURE);
}
}
最佳答案
帕夏(Pasha),您在正确地做一些事情,但随后却使您想做的事情变得更加困难。首先,避免在代码中使用幻数,例如char name[10000];
。代替:
...
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
char line[MAXC];
...
:)
fgets()
读取文件之前,您在打开文件并验证文件已打开以进行读取方面做得很好。您可以在单个块中进行验证并在那时处理错误-这样可以减少整个代码其余部分的缩进程度,例如
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
name[MAXC];
,例如
while (fgets (line, MAXC, fp)) { /* read each line of input */
char name[MAXC]; /* storage for name */
int val; /* integer value for val */
val
声明为
int
,并且将使用
sscanf
解析
name
并将
val
当时的值直接转换为
int
)
fgets()
或POSIX
getline()
)时,您都希望修整读取的
'\n'
并将其包含在填充的缓冲区中。您可以使用
strcspn
轻松地做到这一点。 (请参见
strspn(3) - Linux manual page。这是一个简单的单次调用,您可以使用
strcspn
的返回值作为
'\n'
的索引,以便使用以n终止的字符(即
'\n'
,或简单地
'\0'
)
line[strcspn (line, "\n")] = 0; /* trim '\n' from end of line */
0
中第一个
'#'
的存在,该标记标志注释的开始。如果找到,您将像对
line
那样简单地用n终止字符覆盖
'#'
。
line[strcspn (line, "#")] = 0; /* overwrite '#' with nul-char */
'\n'
和可能出现的所有注释,您可以检查
'\n'
是否为空(这意味着它以
line
开头或只是一个仅包含一个
'#'
)
if (!*line) /* if empty-string */
continue; /* get next line */
'\n'
只是
if (!*line)
的简写。当取消引用缓冲区时,例如
if (line[0] == 0)
,您只是以指针表示形式将第一个元素(第一个字符)作为
*line
返回,与数组中的
*line == *(line + 0)
等效。 -index表示法。
*(line + 0) == line[0]
也用作取消引用。)
[]
直接从
name
解析
val
和
line
。
sscanf
和
"%s"
转换说明符都将忽略转换说明符之前的所有前导空格。只要
"%d"
本身不包含空格,就可以使用此简单方法。就像验证文件打开的返回结果一样,您也将验证
name
的返回结果,以确定您指定的转换次数是否成功发生。例如:
if (sscanf (line, "%1023s %d", name, &val) == 2) /* have name/value? */
printf ("\nline: %s\nname: %s\nval : %d\n", line, name, val);
else
printf ("\nline: %s (doesn't contain name/value\n", line);
sscanf
),可以保护
"%1023s"
的数组边界。字段宽度限制了
name
不得将多个
sscanf
写入名称。这无法提供变量或宏,这是必须在代码中加上一个魔术数字的场合之一。对于每个规则,通常都有一两个警告。)
1023 char + \0
返回了
sscanf
,则您知道请求的两次转换均成功。此外,由于您为
2
指定了整数转换,因此可以保证该值将包含一个整数。
val
读取),则操作完成。一个完整的例子可能是:
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
char line[MAXC];
/* use filename provided as 1st argument (stdin by default) */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
while (fgets (line, MAXC, fp)) { /* read each line of input */
char name[MAXC]; /* storage for name */
int val; /* integer value for val */
line[strcspn (line, "\n")] = 0; /* trim '\n' from end of line */
line[strcspn (line, "#")] = 0; /* overwrite '#' with nul-char */
if (!*line) /* if empty-string */
continue; /* get next line */
if (sscanf (line, "%1023s %d", name, &val) == 2) /* have name/value? */
printf ("\nline: %s\nname: %s\nval : %d\n", line, name, val);
else
printf ("\nline: %s (doesn't contain name/value\n", line);
}
if (fp != stdin) /* close file if not stdin */
fclose (fp);
}
stdin
和注释之前打印原始的
line
,只需在调用
'\n'
之前将
line
的打印内容移动。
strcspn
上方的内容将显示< cc>在调用
line
之前)
line
中的输入文件,您只需执行以下操作即可读取从
sscanf
重定向的值:
$ ./bin/parsenameval <dat/nameval.txt
line: a 12
name: a
val : 12
line: b 33
name: b
val : 33
line: nice 6
name: nice
val : 6
dat/nameval.txt
即可真正打开并从文件中读取,而不必让Shell为您完成。六对一,六对六。)
关于c - C程序读取文件读取额外的一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58686673/
我配置了我的RouteInitializer如下: class AppRouteInitializer implements RouteInitializer { init(Router rout
我正在尝试从 Android 应用程序发送短信。我正在使用 PendingIntent 以便我可以使用 Broadcast Receiver 检查它是否发送正常。由于 sendTextMessage
目录 简介 1 "额外"字段是什么 1.1 "额外"是指与业务无关 1.2 产生
应用程序读取 JSON 数据。然后它会将其放入 ListView (正确),但在按下某个项目后,我总是会得到显示的相同值。下面的代码我认为是问题所在,但我找不到。 try{ JSONArray
我正在使用以下代码 (Kotlin) 创建通知 val builder = NotificationCompat.Builder(ctx) ........ .set
我有一个问题。现在我正在使用 3 个面板,mainPanel 和其他 2 个面板(btnPanel 和 iconPanel)。所以问题是当我按下“重置”按钮时,我删除了 iconPanel 并再次添加
这是我的 html: Settings Export Import 和CSS: span.button { float:right; margin-righ
我正在尝试将一个结构编码为 JSON,然后将其插入我的 Mongo 数据库,但不断出现此错误:%!(EXTRA main.Test={575590180 Me})。我究竟做错了什么?我完全从我从事的另
嘿,我遇到了这些 latex 格式问题,有人可以提供一些帮助吗? .tex 文件: \begin{table}{} \renewcommand{\arraystretch}{1.1} \c
我在 FragmentPagerAdapter 中使用了 Fragment 的 ArrayList。 我想在 saveState() 中保存此 ArrayList 的状态,并在 restoreStat
我做了this MapKit-教程 一切正常,但如何为我的 pin 添加额外的属性? 这是我的课车: import Foundation import MapKit class Car: NSObje
关于 Android intent 将提供的附加功能有哪些文档? 更新: 我做了一些进一步的调查。我知道我们可以假设每个 Intent 都不会解析任何数据或额外内容,除非有明确记录。此外,一些(但不是
我在 python3.4.3 上使用 SqlAlchemy 来管理 MySQL 数据库。我正在创建一个表: from datetime import datetime from sqlalchemy
我正在使用 bootstrap 创建网页。我在两个 block (内容和标题)上派生了正文。在内容 block 中,我有 div 类 .container .sameTable 在里面我有 div 类
我在Windows 7上的MinGW和MSYS下使用gfortran构建了一些fortran程序。但是当我在未安装MinGW和MSYS的其他计算机上运行它们时,系统总是要求一些dll,例如libgfo
第一个元素的右侧似乎有额外的间距,我不知道它是从哪里来的。有人可以帮助我吗? 这是我使用的代码: http://jsfiddle.net/srabeat/tenx4y1c/1/ for (i = 0;
我使用 fs-extra 收到以下错误: ERROR { [Error: EPERM: operation not permitted, unlink 'C:\Projects\xxx\branche
我正在尝试在 CBC 模式下使用 AES-128 加密 320 字节的二进制数据,并将密码存储到一个文件中。输出文件应该是 320 字节,但我得到了 336 字节。这是我的代码: #include
我有一个特定的要求,我必须从我的 Activity 中触发浏览器上的 url。我可以使用以下代码执行此操作: Intent browserIntent = new Intent( Intent.A
我正在使用 JMS DI 注入(inject)带有注解的服务: use JMS\DiExtraBundle\Annotation as DI; /** * @DI\Service("foo.bar.
我是一名优秀的程序员,十分优秀!