逐行读取csv文件并输出第五列以用于c中的匹配

逐行读取csv文件并输出第五列以用于c中的匹配,c,string,csv,line,C,String,Csv,Line,我是C语言的新手,我正在试图找到一种方法来读取csv文件并输出行中的第五个文本,直到eof 我的数据如下所示: 2012年2月5日 00:00:01.548,XOLT,1ZE86V280394811433,追踪包裹,1982年11月23日,美国, 05/02/2012 00:00:01.605,克奥尔特,1ZVRZVOAGNTUNZI,哈迪斯,50.16.47.103,美国,弗吉尼亚州 05/02/2012 00:00:01.647,美国弗吉尼亚州哈迪斯市1ZBHOY21MGFHRNVY区XOL

我是C语言的新手,我正在试图找到一种方法来读取
csv
文件并输出行中的第五个文本,直到eof

我的数据如下所示:

2012年2月5日 00:00:01.548,XOLT,1ZE86V280394811433,追踪包裹,1982年11月23日,美国, 05/02/2012 00:00:01.605,克奥尔特,1ZVRZVOAGNTUNZI,哈迪斯,50.16.47.103,美国,弗吉尼亚州 05/02/2012 00:00:01.647,美国弗吉尼亚州哈迪斯市1ZBHOY21MGFHRNVY区XOLT,50.19.203.230 05/02/2012 00:00:02.275,XOLT,1Z4217060300279193,追踪包裹,107.21.159.246,美国东部, 05/02/2012 00:00:02.599,XOLT,1Z9X98040398954479,瀑布制造,66.117.15.81,美国内华达州 05/02/2012 00:00:02.639,XOLT,1Z3X252W0363295735,追踪包裹,107.22.101.79,美国东部

我需要读取此文件并存储第五个文本(例如23.22.11.82)的值,然后使用它进一步处理匹配

在java中,我使用以下代码分割csv行

String delims = "[,]"; 

while ((s1 = in.readLine()) != null && s1.length() != 0){

            String[] tokens = s1.split(delims); 
C中有类似的方法吗?如果我用C语言运行,我的代码运行得更快,这就是原因

我能够尝试一些c代码,我能够读取文件(3条记录),但它似乎看不到行尾,我遇到了一个分段错误。 我正在使用fgets和strtok

输入文件是一个由逗号(,)组成的可变长度文件分隔符,我希望在每行中获取第五个标记,然后将其用作查找键

代码如下:

    #include "GeoIP.h"
#include "GeoIPCity.h"


static const char * _mk_NA( const char * p ){
 return p ? p : "N/A";
}

int 
main(int argc, char *argv[])
{
  FILE           *f;
  FILE           *out_f;
  GeoIP          *gi;
  GeoIPRecord    *gir;
  int             generate = 0;
  char            iphost[50];
  char            *nextWordPtr = NULL;
  int             wordCount =0;
  char            *rechost;
  char            recbuffer[1000];
  char delims[]=",";
  const char     *time_zone = NULL;
  char          **ret;
  if (argc == 2)
    if (!strcmp(argv[1], "gen"))
      generate = 1;

  gi = GeoIP_open("../data/GeoIPCity.dat", GEOIP_MEMORY_CACHE);

  if (gi == NULL) {
    fprintf(stderr, "Error opening database\n");
    exit(1);
  }

  f = fopen("city_test.txt", "r");

  if (f == NULL) {
    fprintf(stderr, "Error opening city_test.txt\n");
    exit(1);
  }

  out_f = fopen("out_city_lookup_test.txt", "w");

  if (out_f == NULL) {
    fprintf(stderr, "Error opening out_city_lookup_test.txt\n");
    exit(1);
  }

//** Read the file line by line and get the ip address to use to lookup GeoIP **//
//*     while (!feof(f)) {
   while (fgets(recbuffer,1001,f) != NULL {
         nextWordPtr = strtok (recbuffer,delims); 
         while (nextWordPtr != NULL & wordCount < 5) {
           printf("word%d %s\n",wordCount,nextWordPtr);
           if (wordCount == 4 ) {
               printf("nextWordPtr %s\n",nextWordPtr);
               strcpy(iphost, nextWordPtr);
               printf("iphost %s\n",iphost);
           }    
           wordCount++;
           nextWordPtr = strtok(NULL,delims);
         }
    gir = GeoIP_record_by_name(gi, (const char *) iphost);

    if (gir != NULL) {
      ret = GeoIP_range_by_ip(gi, (const char *) iphost);
      time_zone = GeoIP_time_zone_by_country_and_region(gir->country_code, gir->region);
      printf("%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d\t%s\t%s\t%s\n", iphost,
         _mk_NA(gir->country_code),
         _mk_NA(gir->region),
         _mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)),
         _mk_NA(gir->city),
         _mk_NA(gir->postal_code),
         gir->latitude,
         gir->longitude,
         gir->metro_code,
         gir->area_code,
         _mk_NA(time_zone),
         ret[0],
         ret[1]);
      fprintf(out_f,"%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d\t%s\t%s\t%s\n", iphost,
         _mk_NA(gir->country_code),
         _mk_NA(gir->region),
         _mk_NA(GeoIP_region_name_by_code(gir->country_code, gir->region)),
         _mk_NA(gir->city),
         _mk_NA(gir->postal_code),
         gir->latitude,
         gir->longitude,
         gir->metro_code,
         gir->area_code,
         _mk_NA(time_zone),
         ret[0],
         ret[1]);
      GeoIP_range_by_ip_delete(ret);
      GeoIPRecord_delete(gir);
    }
  }
  GeoIP_delete(gi);

  fclose(out_f);

  return 0;
#包括“GeoIP.h”
#包括“GeoIPCity.h”
静态常量字符*_mk_NA(常量字符*p){
返回p?p:“不适用”;
}
int
main(int argc,char*argv[])
{
文件*f;
文件*out\u f;
GeoIP*gi;
地理记录*gir;
int=0;
char-iphost[50];
char*nextWordPtr=NULL;
int字数=0;
char*rechost;
char recbuffer[1000];
字符delims[]=“,”;
常量字符*时区=空;
字符**ret;
如果(argc==2)
如果(!strcmp(argv[1],“gen”))
生成=1;
gi=GeoIP_open(“../data/geoicity.dat”,GeoIP_MEMORY_CACHE);
if(gi==NULL){
fprintf(stderr,“打开数据库时出错\n”);
出口(1);
}
f=fopen(“city_test.txt”,“r”);
如果(f==NULL){
fprintf(stderr,“错误打开city_test.txt”);
出口(1);
}
out_f=fopen(“out_city_lookup_test.txt”,“w”);
如果(out_f==NULL){
fprintf(stderr,“打开城市查找测试时出错”);
出口(1);
}
//**逐行读取文件并获取用于查找GeoIP的ip地址**//
//*而(!feof(f)){
while(fgets(recbuffer,1001,f)!=NULL{
nextWordPtr=strtok(recbuffer,delims);
while(nextWordPtr!=NULL&wordCount<5){
printf(“单词%d%s\n”,字数,nextWordPtr);
如果(字数=4){
printf(“nextWordPtr%s\n”,nextWordPtr);
strcpy(iphost,nextWordPtr);
printf(“iphost%s\n”,iphost);
}    
字数++;
nextWordPtr=strtok(NULL,delims);
}
gir=按名称(gi,(常量字符*)iphost)记录的GeoIP;
如果(gir!=NULL){
ret=地理范围(gi,(常量字符*)iphost);
时区=按国家和地区划分的地理时区(gir->country\u code,gir->region);
printf(“%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d\t%s\t%s\t%s\n”,iphost,
_mk_NA(gir->国家代码),
_mk_NA(gir->region),
_mk_NA(地理区域名称按地理编码(gir->country_code,gir->region)),
_mk_NA(吉尔->城市),
_mk_NA(gir->邮政编码),
gir->纬度,
gir->经度,
gir->metro\u代码,
gir->area\U代码,
_mk_NA(时区),
ret[0],
ret[1]);
fprintf(输出,“%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%d\t%d\t%s\t%s\n”,iphost,
_mk_NA(gir->国家代码),
_mk_NA(gir->region),
_mk_NA(地理区域名称按地理编码(gir->country_code,gir->region)),
_mk_NA(吉尔->城市),
_mk_NA(gir->邮政编码),
gir->纬度,
gir->经度,
gir->metro\u代码,
gir->area\U代码,
_mk_NA(时区),
ret[0],
ret[1]);
通过删除(ret)确定地理范围;
地理信息记录删除(gir);
}
}
GeoIP_删除(gi);
fclose(out_f);
返回0;

是的,没有那么优雅,但你可以用它来完成工作。

对于你想要的,更好的方法是a。如果你的最终目标很复杂,你可能也需要a


我有一个示例lexer和parser。它比你需要的要复杂。如果你想要简单的东西,我会做这项工作,但你会有一些令人不快的惊喜要注意。除了你在这里介绍的简单案例之外,它也很难使用。

是的,有,使用。你自己创建这个CSV文件吗?CSV文件“标准”比使用逗号拆分复杂得多(例如,您可以通过将字符串放在引号中使其包含逗号)。您可能应该使用,它经过优化以有效处理CSV。@M.M我正在使用一个应用程序中的文件,该应用程序使用逗号(,)作为分隔符创建数据。在这组数据中,逗号作为分隔符是唯一的。我使用了以下代码,遇到了分段错误error@Stephen..代码附在上面..希望您能帮助我..代码在读取三条记录后运行,但似乎无法识别记录的结尾或文件的结尾..@EB,您已经构建了一个穷人的lexer。这个东西是充满了潜在的bug,正如你所发现的,实际上有一些bug。我建议你阅读我链接的lexer手册并重新构建它。如果你不能或不愿意,gnu调试器将帮助你找到你的代码没有按预期工作的地方。@Stephen..我不确定从哪里开始..解析代码是导致我的问题的代码,你说首先,它不是一个好的模板..只是验证..谢谢你的反馈,但我没有使用gnu调试器,因为它在c中是新的..所以我