简体   繁体   English

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

[英]Reading a comma separated file into an integer array

Iam trying to read a text file containing integers into an integer array. 我试图将包含整数的文本文件读入整数数组。 If the Input is: 1 3 4 5 6 (with space in between) It is working fine. 如果输入为:1 3 4 5 6(中间有空格)它工作正常。

but if the input is: 1,3,4,5,6 (comma separated) .Its just printing 1.(first digit).If the program finds 1,3,4,5,6 as a single entity then it should print 1,3,4,5,6 as the first index ryt? 但如果输入是:1,3,4,5,6(逗号分隔)。它只是打印1.(第一个数字)。如果程序发现1,3,4,5,6作为单个实体,那么它应该打印1,3,4,5,6作为第一个指标ryt? And also File>>x , does this expression take value one by one by detecting the space in between?? 而且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;
}

What's happening here is that after the first letter is extracted, your code tries to extract the comma as an integer. 这里发生的是在提取第一个字母后,您的代码尝试将逗号提取为整数。 As it cant do this, it will return false and end the loop. 因为它无法做到这一点,它将返回false并结束循环。

There is a very similar question here . 有一个非常类似的问题在这里

Your while loop should look like this: 你的while循环应该如下所示:

while(File>>x)
{
    arr[n] = x; 
    n++;
    if (ss.peek() == ',')
        ss.ignore();
}

Its most likely that when you enter that with commas into the file it is reading it as one whole string. 当你用逗号输入文件时,它最有可能是将它作为整个字符串读取。 Make sure that theres a delimiter for comma also, I don't know where you would be putting the comma in this code, but you need a delimiter nonetheless. 确保这也是逗号的分隔符,我不知道你将逗号放在这个代码中的哪个位置,但是你需要一个分隔符。

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

but if the input is: 1,3,4,5,6 (comma separated) .Its just printing 1.(first digit). 但如果输入是:1,3,4,5,6(逗号分隔)。它只是打印1.(第一个数字)。 If the program finds 1,3,4,5,6 as a single entity then it should print 1,3,4,5,6 as the first index ryt? 如果程序找到1,3,4,5,6作为单个实体,那么它应该打印1,3,4,5,6作为第一个索引ryt?

It prints just "1" because you attempt to read "1,3,4,5,6" into an int object. 它只打印“1”,因为您尝试将“1,3,4,5,6”读入int对象。 An int , however, cannot be "1,3,4,5,6". 但是, int不能是“1,3,4,5,6”。 Plainly speaking, parsing stops as soon as the first "bad" character, ie the comma, is reached, and you end up with the integer number that has been built up so far, ie "1". 简单地说,一旦达到第一个“坏”字符(即逗号),解析就会停止,并且最终得到到目前为止已建立的整数,即“1”。

The rest of the input is discarded. 其余的输入被丢弃。 It's as if your line was "1abcdef", or "1abcdef2345". 这就像你的行是“1abcdef”或“1abcdef2345”。

And also File>>x , does this expression take value one by one by detecting the space in between?? 而且File >> x,这个表达式通过检测两者之间的空间来逐个取值?

Yes, and that makes it quite inflexible. 是的,这使得它非常不灵活。

What I recommend instead of fiddling with operator>> is using std::getline , passing ',' as delimiter. 我建议而不是摆弄operator>>使用std::getline ,传递','作为分隔符。 While the function's name then no longer makes sense, because it no longer reads lines (as it would with the default delimiter '\\n' ), it will work just fine. 虽然函数的名称不再有意义,因为它不再读取 (就像使用默认分隔符'\\n' ),它将正常工作。

You will end with up with individual std::string objects which are easy to convert to int s using std::stoi . 最后将介绍使用std::stoi轻松转换为int的单个std::string对象。

While you're at it, get rid of the raw int arr[100] and make it a std::vector<int> , so that you are not limited to 100 elements. 当你在它的时候,摆脱raw int arr[100]并使它成为std::vector<int> ,这样你就不仅限于100个元素。 100 is an ugly magic (arbitrary) number, anyway. 无论如何,100是一个丑陋的魔法(任意)数字。

Here is an example: 这是一个例子:

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

As you can see, I've also taken the chance to propose some other good C++ practices, such as avoiding using namespace std and std::endl . 正如您所看到的,我还借此机会提出了一些其他优秀的C ++实践,例如避免using namespace stdstd::endl

Have you tried using sscanf with ifstream? 您是否尝试过使用ifstream的sscanf? A simple example below 一个简单的例子如下

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM