我有一个文件,其中包含某人的姓名,他们所在的课程以及名单
离。和John.Smith:11:F12
目前输出是
George.Clooney
Jennifer.Lawrence
Kevin.Bacon
15:S13
15:F15
15:F15
如何摆脱课程参考的冒号?我希望它看起来像这样
15S13
我的代码
struct studentinfo
{
string name;
string classref;
};
void readNumbers(istream &input, char *argv[], int argc)
{
string program = argv[0];
string text = argv[1];
studentinfo array[10];
string name;
int i=0;
if(text=="students.txt"){
while(!getline(input, array[i].name, ':').eof()){
input >> array[i].classref;
i++;
}
for(int j=0; j < i; j++){
cout<< array[j].name << endl;
}
for(int i=0; i < 10; i++){
cout << array[i].classref << endl;
}
}
答案 0 :(得分:2)
这是这个问题的几次迭代的答案,因此上面提到的内容可能看起来有点不合适。
问题是您使用std::getline
来阅读&#39;:&#39;字符。然后使用重载的运算符>>
作为std::string
,再次读取相同的字符串name
覆盖它。这次它读到行尾。
调用std::getline
后,变量name
包含John.Smith
,然后您通过执行input >> name;
立即覆盖该值。这与getline
基本相同,没有指定分隔符的能力。然后,字符串name
包含11:F12
,您可以将其复制到数组中以便稍后显示。
我认为您对getline
的工作原理感到困惑,但您并不需要使用>>
来读取名称值,因为它已经在字符串name
中。你只需要阅读剩下的部分并丢弃它。我建议您阅读std::getline
的在线参考资料,以便更好地了解其工作原理。
要解决您的问题,您可以执行以下任何操作。
name
复制到数组并丢弃该值后,它会清除该行的其余部分,然后在循环getline
调用中读取下一个名称。实现此目的的一种稍微晦涩的方法是在将input >> name;
添加到数组的行之后移动name
。find
成员函数)第一次出现&#39;:&#39;并使用一个子字符串直到该字符(使用substr
成员函数)。有些代码或多或少地符合我的建议。
#include<fstream>
#include<iostream>
#include<string>
using namespace std;
void readNumbers(istream &input)
{
string array[10];
string name;
string garbage;
int i=0;
while(getline(input, name, ':'))
{
array[i]=name;
i++;
input >> garbage;
}
for(int i=0; i<10; i++) cout<< array[i] << '\n';
}
void readNumbers2(istream &input)
{
string array[10];
string ln;
int i=0;
while(getline(input, ln))
{
size_t colpos = ln.find(':');
if(colpos != string::npos)
{
array[i]=ln.substr(0, colpos);
i++;
}
}
for(int i=0; i<10; i++) cout<< array[i] << '\n';
}
struct studentinfo
{
string name;
string classref;
};
void readNumbers3(istream &input)
{
studentinfo array[10];
string name;
int i=0;
while(getline(input, array[i].name, ':'))
{
input >> array[i].classref;
i++;
}
for(int j=0; j < i; j++)
cout<< "name=" << array[j].name << '\n';
}
int main()
{
std::ifstream f("students.txt");
readNumbers(f);
}
当然,这不会处理边缘情况,例如文件中的空行或超出数组,但它演示了std::getline
的使用。我还建议您查看std::vector
或std::array
以保留字符串并使用迭代器或基于范围的循环来打印值。
要从字符串中删除冒号,可以使用以下方法。使用find
查找冒号字符索引和string::erase
的单个迭代器重载以删除该位置的字符。
void charerase()
{
std::string s("15:F15");
std::cout << s << '\n';
size_t cpos = s.find(':');
if(cpos != std::string::npos)
{
s.erase(s.begin() + cpos);
}
std::cout << s << '\n';
}
为此,您需要添加标题<iterator>
。