1

我是 Mac Xcode (3.2.2) 用户,使用 GCC 4.2 编译器,对 C++ 相当缺乏经验,对编译器完全一无所知。

我需要从外部文件中读取数字并将它们存储在整数向量中。我使用流和 getline() 编写代码。我可以编译代码,它运行没有错误,但没有输出。不过,它适用于朋友(非 Mac 和非 GCC 4.2 编译器)。

我做了一些谷歌搜索,发现了几篇关于 Xcode 3.2.1 中可能的编译器(gcc,Apple)问题的帖子,这可能与我的问题有关(例如:C++ using getline() prints: pointer being free was not assigned in XCode。但是,我有 Xcode 3.2.2。我尝试了建议的修复程序(与将 _GLIBCXX_FULLY_DYNAMIC_STRING 添加到(1)目标设置窗口或(2)作为包含之前的预处理器宏),但我的问题仍然没有解决。

所以我现在不知道我的问题是什么——它是否与人们在 Xcode 3.2.1 中遇到的编译器问题相同,但在 3.2.2 中需要不同的修复。或者,如果我的代码中还有其他问题。

如果有人可以提供一些建议,那就太好了。没有什么建议太简单了。如果有另一种从外部文件导入数字的方法,我很想知道。另外,有谁知道是否有任何理由可以从 .dat 文件导入数据,但不能从 Mac 上的 .txt 文件导入数据?

谢谢你。

自从第一次发布以来,我已经包含了 wilhelmtell 的编辑。

目标:将文本文件中的数字读入称为“结果”的整数向量。

1)数据文件test.dat中的数据最初看起来像,

//测试

测试

'1' '2' '3'

// 文本文件中也有标签和注释,我不想读入但又不能从文件中删除。

#include <algorithm>
#include <cctype>
#include <iterator>
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>

using namespace std;

// Edited: added struct (wilhelmtell's advice)
struct not_digit_and_not_whitespace {
    bool operator()(char c) const {
        return ! std::isdigit(c) && ! std::isspace(c);
    }
};

int main()
{
    system("pwd");

    std::string line;
    const std::string fileName = "/Users/me/test.dat";  

    ifstream theStream( fileName.c_str() ); 

    if( ! theStream )
          std::cerr << "Error opening file test.dat\n";

    std::getline( theStream, line );
    // line.erase(remove( line.begin(), line.end(), '\'' ), line.end() ); // Edited (wilhelmtell's advice)
    line.erase(remove_if( line.begin(), line.end(),not_digit_and_not_whitespace()), line.end() );  // Edited: added (wilhelmtell's advice)

    std::istringstream myStream( line );
    std::vector<int> numbers((std::istream_iterator<int>(myStream)), std::istream_iterator<int>());

    std::copy(numbers.begin(), numbers.end(),
              std::ostream_iterator<int>(std::cout, "\n"));

    /* int temp;  // Edited: wilhemtell suggested using iterators instead.
    while ( myStream >> temp ){
        numbers.push_back( temp );
     std::cout << temp << std::endl;
    }*/
    return 0;
}
4

2 回答 2

1

这可能对你有用。它像您尝试的那样使用 getline ,但使用 '\'' 字符作为行分隔符。忽略直到第一个 '. 假设下一个 ' 之前的所有内容都是数字的一部分。继续直到逻辑失败(可能是由于文件结束)。

#include <fstream>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <iterator>

int main()
{
    system("pwd");

    std::string line;
    const std::string fileName = "test.dat";  

    std::ifstream theStream( fileName.c_str() ); 

    if( ! theStream )
          std::cerr << "Error opening file test.dat\n";

    std::vector<int> numbers;

    while (true)
    {
        // get first '
        std::getline(theStream, line, '\'');
        // read until second '
        std::getline(theStream, line, '\'');
        std::istringstream myStream( line );
        int i;
        myStream >> i;
        if (myStream.fail())
            break;
        numbers.push_back(i);
    }
    std::copy(numbers.begin(), numbers.end(),
              std::ostream_iterator<int>(std::cout, "\n"));
}
于 2011-02-14T23:50:26.443 回答
0

我的猜测是您的 test.dat 文件不在工作目录中。要验证您是否可以测试流:

if( ! theStream )
    std::cerr << "Error opening file test.dat\n";

检查 XCode 中的项目属性以查看工作目录是什么,然后将文件放在那里。

如果您的文件包含不解析为整数的数据,则流的int解析将失败。确保您阅读的行只有整数和空格:

#include <cctype>  // algorithm iterator ...

struct not_digit_and_not_whitespace {
    bool operator()(char c) const {
        return ! std::isdigit(c) && ! std::isspace(c);
    }
};

// ...
line.erase(remove_if( line.begin(), line.end(),
                     not_digit_and_not_whitespace()),
           line.end() );

此外,您可以简化代码。首先,如果包含,<iostream>则不需要<istream>. 其次,您可以使用范围构造函数std::vector来获取整数。

#include <algorithm>  // iterator fstream iostream vector string sstream

int main()
{
    std::string line;
    std::ifstream theStream("test.dat");
    std::getline(theStream, line);
    line.erase(std::remove(line.begin(), line.end(), '\'' ),
               line.end());
    std::istringstream myStream(line);
    std::vector<int> numbers((std::istream_iterator<int>(myStream)),
                             std::istream_iterator<int>());
    std::copy(numbers.begin(), numbers.end(),
              std::ostream_iterator<int>(std::cout, "\n"));
    return 0;
}
于 2011-02-14T21:12:13.497 回答