簡體   English   中英

解析選項卡分隔數據

[英]Parsing tab separated data

我有一個文本文件(~10GB),格式如下:

data1<TAB>data2<TAB>data3<TAB>data4<NEWLINE>

我想掃描它並僅對data2進行處理。 在C ++中提取data2的最佳(最快)方法是什么?

編輯:添加NEWLINE

逐行讀取文件。 對於每一行,在選項卡上拆分。 這將為您提供包含字段的數組,允許您使用第二個字段(data2)。

這聽起來像是shell工具等更高級工具的工作:

cut -f2           # from stdin
cut -f2 <my_file  # from file

但是,你也可以用C ++做到這一點:

void parse(std::istream& in)
{
    std::string word;
    while( in ) {
        std::cin >> word;  // throwaway 1
        std::cin >> word;  // data2
        process(word);
        std::cin >> word >> word;  // throwaway 3 and 4
    }
}

// ...
parse(std::cin);
std::ifstream file("my_file");
parse(file);

好吧,打開一個文件流(應該能夠處理10gig文件),然后跳轉到第一個標簽后面,這是'\\t' ,讀取你的數據,然后跳到下一個換行符並重復。

#include <fstream>
#include <string>

int main(){
  std::fstream fin("your_file.txt");

  while(fin){
    std::string data2;
    char sink = '\0';

    // skip to first tab
    fin.ignore(1024,'\t');

    fin >> data2;
    // do stuff with data2

    // skip to next line
    fin.ignore(1024,'\n');
  }
}

一次讀一行文件。 從那里解析標簽很簡單。 您可以使用類似strtok()或類似例程的東西。

由於文件的大小相當大,您可以考慮使用一種技術,使您可以將I / O與處理重疊。 作為回應,你提到你正在研究linux。 如果您使用的是內核2.6或更高版本,則可以考慮使用Linux異步I / O(AIO)。 具體來說,您將使用aio_read排隊一些讀取請求,然后使用aio_suspend等待一個(或多個)請求結束。 當請求完成時,您將使用普通char *掃描緩沖區以找到您感興趣的數據。對於您發現的每一段數據,您可以創建一個std :: string(盡管避免復制可能是有益的)並且處理它。 掃描一個塊后,您將對其進行重新排隊以從文件中讀取另一個塊。 在處理完文件中的每個塊之前,請繼續執行此操作。

此方法的代碼將比逐行讀取文件更復雜,但可能要快得多。

您可以像其他人建議的那樣使用iostream。 另一種方法是簡單地使用fscanf。 例如:

#include <stdio.h>

...

FILE* fp = fopen(path_to_file, "r");
char[256] data;

while(fscanf(fp, "%*s<tab>%s<tab>%*s<tab>%*s", data))
{
   do what you want with your data
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM