如何在没有换行符CRLF的情况下读取CSV记录\r\n“是吗?”;? 我对C++非常陌生,我一直在试图解决如何将CSV文件读入向量。到目前为止,一切都很好,除了我不知道如何避免在每一个CSV记录的结尾换行

如何在没有换行符CRLF的情况下读取CSV记录\r\n“是吗?”;? 我对C++非常陌生,我一直在试图解决如何将CSV文件读入向量。到目前为止,一切都很好,除了我不知道如何避免在每一个CSV记录的结尾换行,c++,excel,csv,newline,C++,Excel,Csv,Newline,这是我的密码: #include <fstream> #include <iostream> #include <sstream> #include <string> #include <vector> // stream input operator overloaded to read a list of CSV fields std::istream &operator >> (std::istream &a

这是我的密码:

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

// stream input operator overloaded to read a list of CSV fields
std::istream &operator >> (std::istream &ins, std::vector<std::string> &record)
{
    record.clear();

    // read the entire line into a string
    std::string line;
    std::getline(ins, line);

    // using a stringstream to separate the fields out of the line
    std::stringstream ss(line);
    std::string field;

    while (std::getline(ss, field, ';'))
    {
        // add the converted field to the end of the record
        record.push_back(field);
    }
    return ins;
}

// stream input operator overloaded to read a list of CSV fields
std::istream &operator >> (std::istream &ins, std::vector<std::vector<std::string>> &data)
{
    data.clear();

    // add results from record into data
    std::vector<std::string> record;

    bool empty;
    while (ins >> record)
    {
        // check if line has a price
        for (unsigned i = 0; i < record.size(); i++)
        {
            std::stringstream ss(record[2]);
            int price;
            if (ss >> price)
            {
                empty = true;
            }
            else
            {
                empty = false;
            }
        }

        if (empty == true)
        {
            data.push_back(record);
        }
    }
    return ins;
}

int main()
{
    // bidemensional vector for storing the menu
    std::vector<std::vector<std::string>> data;

    // reading file into data
    std::ifstream infile("test.csv");
    infile >> data;

    // complain if theres an error
    if (!infile.eof())
    {
        std::cout << "File does not excist." << std::endl;
        return 1;
    }
    infile.close();


    for (unsigned m = 0; m < data.size(); m++)
    {
        for (unsigned n = 0; n < data[m].size(); n++)
        {
            std::string recordQry;
            recordQry += "'" + data[m][n] + "', ";

            std::cout << recordQry;
        }
        std::cout << std::endl;
    }
    return 0;
}

嗯,我本来打算删除我的答案,但决定重新提交一个,因为不管所有关于
getline
的事实如何,你确实知道你有这个问题。在另一个答案的评论中,我注意到您提到它最初是一个excel文件。嗯,至少在某些情况下,Microsoft会以
\r\n
结尾。这可能是原因吗
getline
仍会删除
\n
,但仍会返回回车符。如果是这样的话,您需要使用我之前共享的方法之一。我希望我已经救赎了自己

我使用
\r\n
检查了写入文件,是的,它将离开
\r
。我在调试中观察了它,甚至当我再次使用
getline
提取它留在字符串中的值时。当它打印到控制台时,它打印值,光标浮动在第一个字母下面

微软显然使用这种风格是为了向后兼容旧机器,旧机器需要两个独立的功能——一个是将头部返回到左边距,另一个是卷起纸张。这听起来像你正在经历的行为吗?

试试:

while (std::getline(ss, field, ';'))
{
    // add the converted field to the end of the record
    record.push_back(field.erase(s.find('\r'));
}
//record.push_back(field.erase(s.find('\r'));
return ins;

如果使用
std::getline
,则分隔符永远不会放入目标字符串中。因此,如果您将其与默认换行分隔符一起使用(就像您在第一个输入运算符中所做的那样),则不会得到任何换行符。请查看我的新解释:)由于站点原因,此问题不应被关闭。这个问题甚至不讨论OP的直接问题,显然是一个“如何做这个”的类型。有用但不是重复:如何在C++中读取和操作CSV文件数据?stackoverflow.com/questions/415515/…非常感谢!第二种选择是显而易见的。。似乎还有很多东西要学!嗯,不过有个小问题。使用选项2从所有元素中删除最后一个元素。我使用了:
if(field.substr(field.size()-1,field.size()=“\n”){record.push_back(field.substr(0,field.size()-1))}else{record.push_back(field)}
但它给了我一个错误:哦,是的,我的代码中确实有这个错误。我没有使用c&p:p,它给了我一个xcode中的
SIGABRT
错误。我现在正在检查它的实际含义……让我头疼……谢谢c.Lang!听起来确实是这样的。但是因为我对编程非常陌生,我还没有开始使用任何工具进行调试。我目前的“调试”方式是到处抛出一些
cout
,以检查结果。:p'\r\n'是windows操作系统的行终止序列。当您读取文件时,它将转换为'\n'(假设以文本模式打开)。这里的问题似乎是Windows操作系统文件已被移动到另一个操作系统而未经转换。UNIX上的行终止顺序为“\n”,在读取文件时会转换为“\n”。没有区别。如果使用适当的工具
dos2unix
unix2dos
转换文件,则这将永远不会是一个错误issue.抱歉,我不明白为什么我可以在这里评论,但在解决方案1中不行。ss永远不会包含\n,字段也不会\n。在“正常”CSV文件中,最后一个字段之间的内容是什么;行尾将是最后一个字段的值,即使它是“”-empty.hmm,原来是excel文件。我只是将其保存为CSV。可能是这样吗?:o但我从其他地方读到CSV记录被换行符终止?是的,它被换行符终止,但您的getline将其从“line”中删除。阅读:here:std::getline(ins,line);您“避免”换行符,但您的问题(我想)就是你没有把最后一个字段推回到记录中
while (std::getline(ss, field, ';'))
{
    // add the converted field to the end of the record
    record.push_back(field.erase(s.find('\r'));
}
//record.push_back(field.erase(s.find('\r'));
return ins;