将逗号分隔的文件读入整数数组中

3
我正在尝试将包含整数的文本文件读入整数数组中。 如果输入为:1 3 4 5 6 (用空格隔开)它可以正常工作。
但是,如果输入为:1,3,4,5,6(逗号分隔), 它只打印1(第一个数字)。如果程序将1,3,4,5,6视为单个实体,则应该将1,3,4,5,6作为第一个索引打印出来吧? 还有File>>x这个表达式会检测其间隔并逐个取值吗?
#include<iostream>
#include<fstream>
#include<string>
using namespace std;

int main()
{    
    int n = 0; //n is the number of the integers in the file ==> 12
    int num;
    int arr[100];
    int x;
    int sum = 0;
    ifstream File;
    File.open("integer.txt");
    if(!File.is_open())
    {
        cout<<"It failed"<<endl;
        return 0;
    }

    while(File>>x)
    {
        arr[n] = x; 
        n++;
    }

    File.close();
    cout<<"n : "<<n<<endl;
    for(int i=0;i<n;i++)
    {
        cout << arr[i] << " ";
    }
    return 0;
}
4个回答

2
这里发生的情况是,提取第一个字母后,你的代码尝试将逗号作为整数提取。由于不能这样做,它会返回 false 并结束循环。
这里有一个非常相似的问题,请参考这里
while 循环应该像这样:
while(File>>x)
{
    arr[n] = x; 
    n++;
    if (ss.peek() == ',')
        ss.ignore();
}

2
但是,如果输入为:1,3,4,5,6(逗号分隔),它只会打印第一个数字1。如果程序将1,3,4,5,6视为单个实体,则应该将1,3,4,5,6打印为第一个索引,对吗?
它仅打印“1”,因为您尝试将“1,3,4,5,6”读入int对象中。然而,int不能是“1,3,4,5,6”。简单地说,解析在到达第一个“坏”字符(即逗号)时停止,您最终得到已经构建的整数数字,即“1”。
输入的其余部分被丢弃。就好像您的行是“1abcdef”或“1abcdef2345”。
另外,“File>>x”这个表达式是通过检测之间的空格一个一个地获取值吗?
是的,这使它非常不灵活。
我推荐的做法不是修改 operator>>,而是使用 std::getline 函数,并将逗号 ',' 作为分隔符传入。虽然此时该函数的名称不再合理,因为它不再读取行(默认分隔符 '\n' 会这样做),但仍可正常工作。
您将得到单独的 std::string 对象,可以很容易地使用 std::stoi 转换为 int
顺带一提,将原始的 int arr[100] 改为 std::vector<int>,这样就不会被限制在100个元素以内。100 这个数字是一个丑陋的魔数(任意值)。
以下是示例:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

int main()
{
    // faking some test file input; behaves like an `std::ifstream`:
    std::istringstream is("1,2,3,4,5");

    std::vector<int> numbers;

    std::string number_as_string;
    while (std::getline(is, number_as_string, ','))
    {
        numbers.push_back(std::stoi(number_as_string));
    }

    std::cout << "n : " << numbers.size() << "\n";
    for(auto&& number : numbers)
    {
        std::cout << number << "\n";
    }
}

正如你所看到的,我也借此机会提出了其他好的C++实践,比如避免使用using namespace stdstd::endl

0

当你将带有逗号的内容输入到文件中时,很可能会将其读取为一个整体字符串。确保逗号也有分隔符,我不知道你在这段代码中要放逗号的位置,但无论如何你都需要一个分隔符。

//example function you can use.
getline( ss, s, ',' )

0
你尝试过使用ifstream的sscanf吗?下面是一个简单的例子。
    #include<iostream>
    #include<fstream>
    #include<string>
    using namespace std;

    int main()
    {
        int n = 0; //n is the number of the integers in the file ==> 12
        int num;
        int arr[100];
        char line[200];
        char *ptr=line;
        int x=0,count=0;
        int sum = 0;
        ifstream File;
        File.open("integer.txt");
        if(!File.is_open())
        {
            cout<<"It failed"<<endl;
            return 0;
        }
        File.getline(line,200);

       while((count=sscanf(ptr,"%d,",&x))>0)
        {
            arr[n] = x;
            n++;
            ptr+=count+1;
        }
        File.close();
        cout<<"n : "<<n<<endl;
        for(int i=0;i<n;i++)
        {
            cout << arr[i] << " ";
        }
        cout<<endl;
        return 0;
    }

ptr+=count+1 是为了跳过分隔符。 - KingOfWigs
因为 OP 使用的是 C++ 而不是 C,而 sscanf 是危险和类型不安全的。您还添加了另一个魔术数字数组 char line [200],用混淆指针变量不必要地复杂化了代码,并使用了 getline 成员函数,所有这些都是非常糟糕的编码风格。 - Christian Hackl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接