【问题标题】:Extract fields and values from text line using C++使用 C++ 从文本行中提取字段和值
【发布时间】:2017-06-07 13:56:16
【问题描述】:

我正在阅读具有以下格式行的文本文件:

date    =20170422,line    =10,index   =3,field   =partType,lock    =productCode1,bookmark=2/19/56,

我需要将字段的名称(日期、行、索引等)及其对应的值提取到char field[]char value[]变量中。如有必要,我可以修改行的格式。

我最初的想法是使用 while 循环并检查 =, 字符,但它变得一团糟,似乎可能有更清洁的方法。

【问题讨论】:

  • 使用strchrgetline() 和字符串代替指向字符数组的指针
  • “干净”的方法是使用适当的解析器,如 Boost.Spirit。否则对于这样一个简单的格式,在“=”上拆分,然后在“,”上拆分片段,然后迭代就可以了。
  • 换句话说:如何标记字符串?问和回答了无数次。由于缺乏研究而被否决。

标签: c++ arrays string file


【解决方案1】:

您可以执行以下示例。使用文件中的 getline 以逗号分割字符串,然后使用 istringstream 和 getline 以等号再次分割。

#include<iostream>
#include<fstream>
#include<string>
#include<sstream>
int main()
{
        std::ifstream file("test.txt");
        std::string wholeLine, partOfLine;
        while(std::getline(file, wholeLine, ',')) {
                std::istringstream wholeLineSS(wholeLine);
                while(std::getline(wholeLineSS, partOfLine, '=')) {
                        std::cout<<partOfLine<<std::endl;
                }
        }
        return 0;
}

【讨论】:

    【解决方案2】:

    我在此处发布的程序从一个或多个按您需要格式化的字符串中提取参数。函数extract 提取字符串(您指定的格式)中包含的所有参数,并将它们的名称和值插入到结构(struct sParms)数组中。

    您可以将程序编译为提取并在系统提示符下执行它:

    用户名:./extract "date =20170422,line =10,index =3,field
    =partType,lock =productCode1,bookmark=2/19/56,"

    输出如下:

    [date]=[20170422]
    [line]=[10]
    [index]=[3]
    [field]=[partType]
    [lock]=[productCode1]
    [bookmark]=[2/19/56]
    

    您可以使用多个字符串执行程序:

    用户名:./extract "date =20170422,line =10,index =3,field
    =partType,lock =productCode1,bookmark=2/19/56," "yes=1, no=0"

    输出如下:

    [date]=[20170422]
    [line]=[10]
    [index]=[3]
    [field]=[partType]
    [lock]=[productCode1]
    [bookmark]=[2/19/56]
    
    [yes]=[1]
    [no]=[0]
    

    下面一行是代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <libgen.h>
    
    //Parameters: date    =20170422,line    =10,index   =3,field   =partType,lock    =productCode1,bookmark=2/19/56,
    #define SEPARATOR       ','
    #define ASSIGNEMENT     '='
    
    typedef struct sParms {
        char * fieldName;
        char * fieldValue;
    } tsParms;
    
    int loadString(char *to, const char *from);
    
    int extract(tsParms **oparms, const char *inb);
    
    // Retrieve buffer length
    int loadString(char *to, const char *from)
    {
        int len=0;
    
        while(*from<=32 && *from!=SEPARATOR && *from!=ASSIGNEMENT)
            from++;
    
        // Get the string value
        while(*from>32 && *from!=SEPARATOR && *from!=ASSIGNEMENT) {
            *(to+len++)=*from;
            ++from;
        }
    
        *(to+len++)=0;
    
        return len;
    }
    
    int extract(tsParms ** oparms, const char *inb)
    {
        int cnt=0,j;
        const char * end, *equ, *start;
        char * buff;
        tsParms * parms;
    
        if (inb == NULL || strlen(inb) == 0 || oparms == NULL)
            return 0;
    
        // It counts the number of parms
        end=strchr(inb,ASSIGNEMENT);
        while(end) {
            cnt++;
            end=strchr(end+1,ASSIGNEMENT);
        }
    
        if (!cnt)
            return 0;
    
        /* Doing some considerations we may assume that the memory to use to store
         * fields name and values is the same of the input string (inb)
         *
         * The space to store the pointers is cnt * sizeof(tsParms *).
         */
    
        j=cnt * sizeof(tsParms) + strlen(inb);
        parms = malloc(j+1);
        memset(parms,0,j+1);
    
        buff = (char *)(parms+cnt); // The memory area where we can save data!
    
        start=inb;end=start;cnt=0;
        do {
            end=strchr(start,SEPARATOR);
            equ=strchr(start,ASSIGNEMENT);
    
            if (equ) {
                //Get the field name
                parms[cnt].fieldName=buff;
                buff+=loadString(buff,start);
    
                //Get the field value
                start=equ+1;
                parms[cnt].fieldValue=buff;
                buff+=loadString(buff,start);
    
                cnt++;
            }
    
            if (end)
                start=end+1;
        } while(end);
    
        *oparms = parms;
    
        return cnt;
    }
    
    int main(int argc, char *argv[])
    {
        int i,j,cnt=0,retval=0;
        tsParms * parms=NULL;
    
        if (argc<2) {
            printf("Usage: %s \"string-1\" [\"string-2\" ...\"string-n\"]\n",basename(argv[0]));
            return 1;
        }
    
        for(i=1; i<argc; i++) {
            cnt=extract(&parms, argv[i]);
    
            if (cnt!=0 && parms!=NULL) {
                for(j=0;j<cnt;j++) {
                    printf("[%s]=[%s]\n",parms[j].fieldName,parms[j].fieldValue);
                }
                puts("");
    
                free((void *)parms);
            } else {
                retval=1;
                break;
            }
        }
    
        return retval;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 2015-06-30
      相关资源
      最近更新 更多