C++ 目瞪口呆地寻找一个可以工作的c&;c++;删除回车符的方法(读取.csv文件)
我通过以下方式读取.csv文件行:C++ 目瞪口呆地寻找一个可以工作的c&;c++;删除回车符的方法(读取.csv文件),c++,c,carriage-return,C++,C,Carriage Return,我通过以下方式读取.csv文件行: vector <string> vec_str; char line[40]; while (1) { memset (line, 0, 40 * sizeof (char)); if (fgets (line, 0, f_str_csv) == NULL) { break; } //and then making strings out of NL trimmed line, and storing
vector <string> vec_str;
char line[40];
while (1) {
memset (line, 0, 40 * sizeof (char));
if (fgets (line, 0, f_str_csv) == NULL) {
break;
}
//and then making strings out of NL trimmed line, and storing them in vec_str as
vec_str.push_back (string (line, strlen (line)).substr (0, strlen (line) - 1));
}
给我一个输出:
[10]
[20]
[James K.
]
对于输入10,20,James K.
,这是我从csv文件中读取的行
这里怎么了
编辑:
同样对于以后的文件,如果一个较小的名称出现在行的末尾,如11,31,Wu S.
在James K.
行之后,我会在buffer
中得到剩余的James K.
,这在第二次迭代后从结果中可以明显看出:
[11]
[31]
[Wu S.
K.
]
有人请告诉我如何避免这种回车错误行为。以下是使用std::getline和std::ifstream的方法:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
#include <vector>
class line {
public:
operator std::string() const {
return data_;
}
friend std::ostream& operator<<(std::ostream& out, const line& self) {
out << self.data_ << std::endl;
return out;
}
friend std::istream& operator>>(std::istream& in, line& self) {
std::getline(in, self.data_);
return in;
}
private:
std::string data_;
};
class csv_part {
public:
operator std::string() const {
return data_;
}
friend std::ostream& operator<<(std::ostream& out, const csv_part& self) {
out << self.data_;
return out;
}
friend std::istream& operator>>(std::istream& in, csv_part& self) {
std::getline(in, self.data_, ',');
return in;
}
private:
std::string data_;
};
int main() {
std::ifstream f_str_csv("myfile.csv");
if(f_str_csv.is_open()) {
std::vector<std::string> vec_str;
// Read all lines from file
std::copy(std::istream_iterator<line>(f_str_csv),
std::istream_iterator<line>(),
std::back_inserter(vec_str));
// loop through all lines read
for(std::vector<std::string>::const_iterator it = vec_str.begin();
it != vec_str.end();
++it) {
std::istringstream is(*it);
// Print every part of the line (separated with a comma),
// separated with a pipe symbol (|)
std::copy(std::istream_iterator<csv_part>(is),
std::istream_iterator<csv_part>(),
std::ostream_iterator<csv_part>(std::cout, "|"));
std::cout << std::endl;
}
} else {
std::cerr << "Could not open input file" << std::endl;
}
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
班级线{
公众:
运算符std::string()常量{
返回数据;
}
friend std::ostream&operator以下是使用和时的简单程度:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <boost/algorithm/string.hpp>
int main(int argc, const char *argv[])
{
std::fstream file;
file.open("input.txt");
std::vector<std::vector<std::string>> lines;
while (!file.eof()) {
std::string line;
// Read a line in the file to replace your C code.
std::getline(file, line);
std::vector<std::string> words;
// Split the words in the line - "\t ," defines the set of delimiters.
boost::split(words, line, boost::is_any_of("\t ,"));
lines.push_back(words);
}
// Oputput each word, you can also replace the range based loops if you don't
// use C++11.
for (const auto& line : lines)
{
for (const auto& word : line)
{
std::cout << word << " ";
}
std::cout << std::endl;
}
file.close();
return 0;
}
使用g++-std=c++11 main.cpp-o main编译程序并执行它将导致:
11 31 James K.
11 31 Wu S.
CSV的某些行读取可能包含\r和/或\n使用C/文件的行尾:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
int main()
{
FILE* f_str_csv = stdin;
std::vector<std::string> vec_str;
const unsigned Length = 4096;
char line[Length];
while (std::fgets(line, Length, f_str_csv) != NULL) {
std::size_t n = std::strlen(line);
if(n) {
if(n + 1 == Length) {
// Overflow
throw std::overflow_error("Overflow");
}
switch(line[n-1]) {
case '\n':
case '\r':
if(--n) {
switch(line[n-1]) {
case '\n':
case '\r':
--n;
}
}
}
if(n) {
char* ln = line;
switch(ln[0]) {
case '\n':
case '\r':
++ln;
--n;
}
if(n) {
vec_str.push_back (std::string (ln, ln + n));
}
}
}
}
for(unsigned i = 0; i < vec_str.size(); ++i)
std::cout << vec_str[i] << '\n';
}
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
文件*f_str_csv=stdin;
std::vec_str;
常量无符号长度=4096;
字符行[长度];
while(std::fgets(行、长度、f_str_csv)!=NULL){
std::size\u t n=std::strlen(行);
如果(n){
如果(n+1==长度){
//溢出
抛出std::溢出_错误(“溢出”);
}
开关(线路[n-1]){
案例“\n”:
案例'\r':
如果(--n){
开关(线路[n-1]){
案例“\n”:
案例'\r':
--n;
}
}
}
如果(n){
char*ln=行;
开关(ln[0]){
案例“\n”:
案例'\r':
++ln;
--n;
}
如果(n){
向量str.push_back(std::string(ln,ln+n));
}
}
}
}
for(无符号i=0;i std::cout由于您已经在使用std::vector和std::string(都是C++),请看我读取的csv文件读取filestreamFILE*f_csv;
?也就是说,因为istream
应该是iostream
的一个子类,而ifstream
是我正在使用的。为什么你不能使用std::ifstream?顺便说一句,我不确定boost是否是我唯一可以使用的方法。感谢面向boost的解决方案,@t奥米斯拉夫·马里奇
11 31 James K.
11 31 Wu S.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdexcept>
#include <string>
#include <vector>
int main()
{
FILE* f_str_csv = stdin;
std::vector<std::string> vec_str;
const unsigned Length = 4096;
char line[Length];
while (std::fgets(line, Length, f_str_csv) != NULL) {
std::size_t n = std::strlen(line);
if(n) {
if(n + 1 == Length) {
// Overflow
throw std::overflow_error("Overflow");
}
switch(line[n-1]) {
case '\n':
case '\r':
if(--n) {
switch(line[n-1]) {
case '\n':
case '\r':
--n;
}
}
}
if(n) {
char* ln = line;
switch(ln[0]) {
case '\n':
case '\r':
++ln;
--n;
}
if(n) {
vec_str.push_back (std::string (ln, ln + n));
}
}
}
}
for(unsigned i = 0; i < vec_str.size(); ++i)
std::cout << vec_str[i] << '\n';
}