我必须从DIMES ASNodes.csv(http://netdimes.org/new/?q=node/65)文件中获取节点ID。 文件看起来像这样:
6067,UNKNOWN,2007-02-03 10:03:53.0,2007-01-02 02:54:13.0,12,6,0
29287,UNKNOWN,2007-02-03 21:11:07.0,2007-01-02 07:33:35.0,1,0,0
...
到目前为止,我想出了这段代码,但它不能正常工作。虽然它打印出我需要的所有数字,但它也打印出两次节点id,有时会在两者之间打印零。感谢您的任何想法
void loadNodes(const char* filename)
{
FILE* nodes = fopen(filename, "r");
unsigned int id = 0;
char line[64];
while (fgets(line, sizeof(line), nodes) != NULL) {
sscanf(line, "%u%*[^\n]", &id);
printf("id = %u\n", id);
}
fclose(nodes);
}
答案 0 :(得分:1)
我认为麻烦的是你的行有63个字符加上换行符,这意味着fgets()
读取但不包括换行符(并且你处理它并得到正确的数字),然后下一个fgets()
读取在前一个输入上留下的换行符(并且你处理它 - 令人惊讶的是你得到零而不是重复前一个数字。)
这是您的代码转换为MCVE(How to create a Minimal, Complete, and Verifiable Example?)main()
程序,该程序从标准输入读取(这使我无需验证,打开和关闭文件):
#include <stdio.h>
int main(void)
{
unsigned id = 0;
char line[64];
while (fgets(line, sizeof(line), stdin) != NULL)
{
printf("Line: [%s]\n", line);
sscanf(line,"%u", &id);
printf("id = %u\n", id);
}
return 0;
}
请注意刚读取的行的诊断打印。代码应该真正检查sscanf()
的返回值。 (跳过尾随碎片没有任何优点,所以我从格式字符串中删除了它。)
给定数据文件(data
):
6067,UNKNOWN,2007-02-03 10:03:53.0,2007-01-02 02:54:13.0,12,6,0
29287,UNKNOWN,2007-02-03 21:11:07.0,2007-01-02 07:33:35.0,1,0,0
我从so.37103830 < data
获得的输出是:
Line: [6067,UNKNOWN,2007-02-03 10:03:53.0,2007-01-02 02:54:13.0,12,6,0]
id = 6067
Line: [
]
id = 6067
Line: [29287,UNKNOWN,2007-02-03 21:11:07.0,2007-01-02 07:33:35.0,1,0,0]
id = 29287
Line: [
]
id = 29287
最简单的解决方法是使用更长的缓冲区长度;我通常使用4096,如果我不关心如果读取了很长的行会发生什么,但你可能会认为128或256就足够了。
否则,我使用POSIX getline()
,它将读取任意长行(不会耗尽内存)。
如果线路长度较长,我会得到输出:
Line: [6067,UNKNOWN,2007-02-03 10:03:53.0,2007-01-02 02:54:13.0,12,6,0
]
id = 6067
Line: [29287,UNKNOWN,2007-02-03 21:11:07.0,2007-01-02 07:33:35.0,1,0,0
]
id = 29287
答案 1 :(得分:0)
假设您只需要文件中的第一列(因为您提到了节点ID),您可以使用:
unsigned int node_id;
char str[100];
while(scanf("%u,%[^\n]",&node_id, str) == 2) {
printf("%u\n",node_id);
}