C++:可能的 Xcode (Mac) 问题。无法使用 getline() 从外部文件读取数字

发布于 2024-10-17 10:58:17 字数 2305 浏览 5 评论 0原文

我是 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 freed was not allocate in ,我有 Xcode 3.2.2。我尝试了建议的修复(与将 _GLIBCXX_FULLY_DYNAMIC_STRING 添加到(1)目标设置窗口或(2)作为包含之前的预处理器宏),但我的问题仍然没有解决。

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

有人可以提供一些建议,那就太好了。如果有其他方法从外部文件导入数字,我也很想知道是否有任何原因。可以从 .dat 文件导入数据,但不能在 Mac 上导入 .txt 文件吗?

谢谢。

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

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

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

//Test

test

'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;
}

I'm a Mac Xcode (3.2.2) user, working with the GCC 4.2 compiler, fairly inexperienced with C++ and completely ignorant about compilers.

I need to read in numbers from an external file and store them in a vector of ints. I wrote code using streams and getline(). I can compile the code and it runs without errors, but there is no output. It works for a friend (non-Mac and non-GCC 4.2 compiler) though.

I did some googling and found several posts about a possible compiler (gcc, Apple) issue in Xcode 3.2.1 that might relate to my problem (this one, for example: C++ using getline() prints: pointer being freed was not allocated in XCode. However, I have Xcode 3.2.2. I tried the suggested fixes (related to adding _GLIBCXX_FULLY_DYNAMIC_STRING to (1) the target settings window or (2) as preprocessor macros before the includes), but my problem is still not solved.

So I don't know what my problem is at this point--whether it is the same compiler issue that people had in Xcode 3.2.1 but a different fix is required in 3.2.2. Or if there is some other problem in my code.

It would be great if someone could offer some advice. No advice is too simple. If there is another way to import numbers from an external file, I would love to know about it. Also, does anyone know if there would be any reason it would be possible to import data from a .dat file, but not a .txt file on a Mac?

Thank you.

Since first posting, I have included wilhelmtell's edits.

Goal: Read numbers from a text file into a vector of ints called "results."

1) The data in the data file test.dat initially looked like,

//Test

test

'1' '2' '3'

// There are also labels and comments in the text file that I don't want to read in but can't delete from the file.

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

微凉 2024-10-24 10:58:17

这可能对你有用。正如您所尝试的那样,它使用 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"));
}

This might work for you. It uses getline as you were trying, but uses the '\'' character to serve as the line delimiter. Ignore everything up to the first '. Assume everything until the next ' is part of a number. Continue until the logic fails (presumably due to end of file).

#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"));
}
轻拂→两袖风尘 2024-10-24 10:58:17

我的猜测是您的 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() );

此外,您还可以简化代码。首先,如果您包含 ,则不需要 。其次,您可以使用 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;
}

My guess is that your test.dat file is not in the working directory. To verify that you can test the stream:

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

Check your project properties in XCode to see what the working directory is, and place the file there.

If your file contains data that doesn't parse as integers then the streams' int parsing will fail. Make sure the line you read has nothing but integers and whitespace:

#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() );

Also, you can simplify your code. First, if you include <iostream> then you don't need <istream>. Secondly, you can use the range constructor of std::vector to get the integers.

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文