【问题标题】:getline to read in a string that has both white spaces and is comma seperatedgetline 读取包含空格且以逗号分隔的字符串
【发布时间】:2016-06-18 19:52:32
【问题描述】:

好的,所以我有一个文件,其中包含这样的字符串:

2012 年 10 月 11 日下午 12:30,67.9,78,98

...

...

我想这样分开

2012 年 10 月 11 日 下午 12:30 67.9

我知道您使用 getline 来分隔逗号分隔的内容:

getline(infile, my_string, ',')

但我也知道这样做是为了获取日期:

getline(infile, my_string, ' ')

会在空格中读入 my_string

那么还有其他方法可以解决这个问题吗? 另外,我需要做什么才能跳过最后 2 (78,98) 并转到下一行?一个getline(infile, my_string) 就够了吗?

【问题讨论】:

  • Relevant/Related。不要使用getline() 进行第一名的解析。
  • 我应该改用什么?
  • 使用getline() 读取整行,使用std::istringstream 进一步解析该行中的值。如有必要,重复这些步骤。

标签: c++ csv getline


【解决方案1】:

你可以用getline读取字符串,然后用sscanf读取格式化后的字符串:)

【讨论】:

  • 不是一个非常 C++ 的解决方案,我认为使用 std::stringstream 至少同样好 - 如果您有可变数量的元素,则更容易。
  • 我认为这只是一个方便的问题。如果文件始终遵循相同的格式,则 sscanf 解决方案将仅在一行中完成 :)
【解决方案2】:

【讨论】:

    【解决方案3】:

    为您的流提供一个将逗号解释为空格的构面(这将是我们的分隔符)。然后只需创建一个重载operator>>() 函数并利用这个新功能的类。 istream::ignore 是要跳过字符时使用的函数。

    #include <iostream>
    #include <vector>
    #include <limits>
    
    struct whitespace : std::ctype<char> {
        static const mask* get_table() {
            static std::vector<mask> v(classic_table(), classic_table() + table_size);
            v[','] |=  space;  // comma will be classified as whitespace
            v[' '] &= ~space;      // space will not be classified as whitespace
            return &v[0];
        }
    
        whitespace(std::size_t refs = 0) : std::ctype<char>(get_table(), false, refs) { }
    };
    
    template<class T>
    using has_whitespace_locale = T;
    
    struct row {
        friend std::istream& operator>>(has_whitespace_locale<std::istream>& is, row& r) {
            std::string temp;
            is >> r.m_row >> temp;
            r.m_row += temp;
            is.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip the rest of the line
            return is;
        }
    
        std::string get_row() const { return m_row; }
    private:
        std::string m_row;
    };
    
    // Test
    
    #include <sstream>
    #include <string>
    int main() {
        std::stringstream ss("10/11/12 12:30 PM,67.9,78,98\n4/24/11 4:52 AM,42.9,59,48");
        std::cin.imbue(std::locale(std::cin.getloc(), new whitespace));
        row r;
        while (ss >> r) {
            std::cout << r.get_row() << '\n';
        }
    }
    

    Coliru Demo

    【讨论】:

      猜你喜欢
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多