2012-02-11 148 views
0

我一直在搜索互联网一段时间,但是我可以在C++中找到的文件输入是当你知道文件名。C++中的文件输入

我正试图编写一个程序来执行一个文件,但不使用scanf或cin的2大于0的数字的添加。我想将文件加载到内存中,但是我可以找到的关于这种情况的所有代码都需要知道文件名。该文件在单行上用2个整数格式化,由空格分隔,并且有多行整数。该程序将输出这两个数字的总和。我可以很容易地用scanf做到这一点,但如果我得到一个大文件,我想将它加载到内存中(稍后保存映射)。

将文件加载到内存中给我带来麻烦,因为我不知道文件名,也不知道如何查找,除非用户输入文件名(不会发生)。我要像这样执行的程序,但使用C++ IO的最原始和基本形式:

./myprog < boatloadofnumbers 

我将如何开始我的计划取整“boatloadofnumbers”为一档,这样我就可以使用更多的基本功能,如read()? (也,所谓上述方法?通过输入?)

int main(){ 
    int a,b; 
    while (scanf("%i,%i",&a,&b)>-1){ 
     printf("%i\n",(a+b)); 
    } //endwhile 
    return 0; 
} //endmain 
+1

'我可以找到的所有文件输入在C++是当你知道文件名.'大声笑。如果您试图从文件中读取数据,而您不知道文件名称是什么,那么您完全是SOL。明显。 – 2012-02-11 21:48:46

+2

您正在从标准输入读取数据,而不是从任何文件读取数据。 shell正在为你重定向。 – 2012-02-11 21:54:52

+0

@KerrekSB我明白了..是否有另一种阅读数据的方式?我想我可以做一些文件操作,如果一个文件被给出,但我看到情况不再是这样了。我一直在尝试使用比scanf更基本的输入方法,或者能够以更大的比例读取数据,而不是按数字编号。你认为你可以指出我正确的方向吗? – 2012-02-11 22:05:06

回答

0

这并不完全清楚如何当你不知道文件名时会读取一个文件。大概你不知道文件名编译时间。没关系,你可以在运行时命令行得到这个,像这样:

./myprog boatloadofnumbers 

那么你的文件名是在argv[1],您可以使用std::ifstream访问它。

如果你正在通过redirection(如./myprog < boatloadofnumbers)你不需要的文件名都,你可以只使用std::cin直接给出对stdin输入。

以下main()将处理这两种情况下:

int main(int argc, char* argv[]) 
{ 
    if (argc == 2) 
    { 
     std::cerr << "Reading from file" << argv[1] << std::endl; 
     std::ifstream ifs(argv[1]); 
     if (ifs) 
     { 
      sum_lines(ifs); 
     } 
     else 
     { 
      std::cerr << "Could not read from " << argv[1] << std::endl; 
     } 
    } 
    else 
    { 
     std::cerr << "Reading from stdin" << std::endl; 
     sum_lines(std::cin); 
    } 
} 

样本sum_lines()可能看起来有点像这样:

void sum_lines(std::istream& is) 
{ 
    int first = 0, second = 0; 
    std::string line = ""; 
    while (std::getline(is, line)) 
    { 
     std::istringstream iss(line); 
     if (is >> first >> second) 
     { 
      std::cout << first << " + " << second << " = " << first + second << std::endl; 
     } 
     else 
     { 
      std::cerr << "Could not parse [" << line << "]" << std::endl; 
     } 
    } 
} 

这并不从输入来自那里的医疗,所以你可以很容易地注入一个std::istringstream进行单元测试。此外,这不会将整个文件读入内存,每次只读一行,所以它应该处理averybigboatloadofnumbers

1

当作为你的状态在程序调用,那么boatloadofnumbers的内容可以从STD阅读:: CIN。

该方法被称为输入重定向由shell而不是您的程序完成。

如果输入重定向,shell通常会缓冲文件的内容。这是通过计算一次性传输文件的非常快速的方式。

+0

那么,输入如何加载到内存中?从我一直在做的事情来看,内容是按数字来读取的,计算被执行,然后被输出。我想阅读比“按数字编号”更大的内容,因为我以文件的形式给出内容。我怎么做? – 2012-02-11 21:58:06

+0

那取决于:请显示您的代码,这需要回答的猜测。 – 2012-02-11 22:00:31

+0

原始帖子中显示的代码。 (所有整数都是> 0 ...可能应该提到那个) – 2012-02-11 22:09:41

0

使用shell重定向,您的程序可以从标准输入读取,这可能是可取的。但是,从文件读取也是可取的。这很容易支持:

cat data > ./prog 
./prog < data 

./prog -f data 

前两个是相似的,而文件data的内容都可以从程序的标准输入;第三行只是传递一个命令行参数。下面是我们如何支持这一点:

#include <cstdio> 
#include <cstring> 

void process_input(std::FILE * fp) 
{ 
    char buf[4]; 
    std::fread(buf, 4, 1, fp); 
    // ... 
} 

int main(int argc, char * argv[]) 
{ 
    std::FILE * fp = stdin; // already open! 

    if (argc >= 3 && 0 == std::strcmp(argv[1]. "-f")) 
    { 
     fp = std::fopen(argv[2], "rb"); 

     if (!fp) 
     { 
      std::fprintf(stderr, "Could not open file %s.\n", argv[2]); 
      return 1; 
     } 
    } 

    process_input(fp); 

    if (fp != stdin) { std::fclose(fp); } 
} 

等价,就可以实现与输入输出流类似的东西,但它更迂回了一下,有一个很好的,通用的参考:

#include <fstream> 

int main() 
{ 
    std::ifstream ifp; 

    if (/* as before */) 
    { 
     ifp.open(argv[2], std::ios::binary); 
     if (!ifp) { /* error and die */ } 
    } 

    std::ifstream & infile = ifp ? ifp : std::cin; 

    process_input(infile); 
}