在c ++程序中执行行计数bash命令(wc -l)

时间:2016-09-15 19:13:46

标签: c++ bash shell

我想在声明全局数组之前计算数据文件行的数量。我知道在终端中如果我执行wc -l filename,我会得到行数。如何使用该命令(wc -l filename)并将其结果存储到c ++程序中的int类型变量中?当我使用以下代码时:  int NT=system(" wc -l file.d"); 我得到NT=0.

如何获得不。在NT中的file.d中的行?

2 个答案:

答案 0 :(得分:2)

什么应该是一个相当有效的解决方案,虽然它不能在POSIX系统之外移植(阅读:您必须重写以在Windows上使用WinAPI等效调用),因为它避免了实际需要构造对象,对每一行执行显式读取等。除了mmap工作(其中大部分可以至少考虑因素),它基本上是一行的。

我一般不推荐这样做(只需使用std::vector或类似内容即可解决您的问题,以便您的数据结构可以动态增长以匹配行数),但我&#39如果你有点好奇,可以把它放在这里。

#include <algorithm>

#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

const char* map_whole_file(const char *filename, size_t& map_size);

int main(...) {
    const char *filename = ...;  // From argv, constant, whatever
    size_t map_size;

    const char *data = map_whole_file(filename, map_size);

    // Number of lines is count of newline characters, +1 if final line not
    // terminated with newline
    size_t numlines = std::count(data, data+map_size, '\n') + (data[map_size-1] != '\n');

    munmap(data, map_size);
}

const char* map_whole_file(const char *filename, size_t& map_size) {
    int fd = open(filename, O_RDONLY);
    if (fd == -1)
        ...handle_error...;

    struct stat sb;
    if (fstat(fd, &sb) == -1)           /* To obtain file size */
        ...handle_error...;

    // Cast only needed because it's C++
    const char *data = (const char *)mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
    if (data == MAP_FAILED)
        ...handle_error...;

    close(fd); // Don't need fd after mapping done

    // Optionally, posix_madvise(data, sb.st_size, POSIX_MADV_WILLNEED);
    // or the like will hint the OS to aggressively page in the file, so
    // count is less likely to be delayed by disk I/O

    map_size = sb.st_size;
    return data;
}

答案 1 :(得分:1)

您可以通过 getline 获取文件中行数的一种方法:

#include <fstream>
#include <iostream>
using namespace std;

int main()
{
    fstream in("file.d");
    int lines = 0;
    string s;
    while (getline(in, s))
    {
        ++lines;
    }
    cout << lines << endl;
    return 0;
}

修改...

更有效的方法(如果你只想要计数而不想使用任何数据)就是使用istream :: ignore,正如Matteo Italia所指出的那样。

#include <fstream>
#include <iostream>
#include <limits>
using namespace std;

int main()
{
    fstream in("in.txt");
    int lines = 0;
    char endline_char = '\n';
    while (in.ignore(numeric_limits<streamsize>::max(), in.widen(endline_char)))
    {
        ++lines;
    }
    cout << lines << endl;
    return 0;
}

无论哪种方式都会输出名为“file.d”的文件中的行数。您可以将其输出与'wc -l'的输出进行比较。