c++ - 标记字符串,识别字符时出错

标签 c++

我在 C++ 的学校作业中遇到了一些麻烦。我遇到的具体问题涉及从包含一系列 5 到 6 年级的文件中读取行。每个学生的成绩一起显示在学生姓名和身份证号码之后的一行中。这里的挑战是,等级之间的空格数量可以变化,如果只有 5 个等级,则需要生成一条错误消息以进行筛选,但程序将继续运行并对 5 个等级进行平均。输入示例:23 46 68 85 98

我很容易得到学生姓名和 ID,但数字串给我带来了问题。我的计划是 getline 然后标记字符串并将每个标记分配给数组中的一个单元格。这适用于 6 个等级,但是当只有 5 个等级存在时,它会将垃圾分配给第六个单元格。

这是与这部分相关的代码片段:

fin.getline(gradeList, 200);

grade = strtok (gradeList, " ");


while (grade != '\0')
{         
      gradeArr[cycler] = atoi(grade);
      grade = strtok(NULL, " ");
      cycler++;
}

我尝试在将每个标记转换为 int 之前对其进行 isdigit 检查,并为未通过 isdigit 检查的任何标记写入 0,但这根本不起作用。当只有 5 个等级存在时,它似乎从下一行中拉出名称,然后当它是它时,它将它更改为一个巨大的数字。

我以为程序做getline的时候,只会抢到行,直到看到endline终止符。这不是正在发生的事情吗?

最佳答案

摒弃 C 废话并使用真正的 C++:

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

// ...

std::vector<int> grades;

std::string line;

while (std::getline(fin, line))
{
    std::istringstream iss(line);
    int grade;

    while (iss >> grade)
    {
        grades.push_back(grade);
    }
}

这里有一个更紧凑和优雅的方法,使用 istream-iterators 和 back-inserters:

#include <iterator>
#include <algorithm>
// other headers as before

std::vector<int> grades;

for (std::string line; std::getline(fin, line); )
{
    std::istringstream iss(line);
    std::copy(std::istream_iterator<int>(iss), std::istream_iterator<int>(),
              std::back_inserter(grades));
}

要点在于,从流中提取格式化的标记 (>>>) 已经完全按照您的意愿进行,并且它包含标记化和解析为整数。

istream_iterator 封装了 token 提取,并允许您将流视为已经解析的 token 序列。 copy 算法然后简单地将这个序列复制到一个 vector 中,并将其插入到容器的末尾。

关于c++ - 标记字符串,识别字符时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9251163/

相关文章:

c++ - 使用 Boost Polygon 的减法结果不正确

c++ - 声明指针时更改 asterick 的位置

c++ - vector 值函数梯度的特征值

c++ - 在 C++ 中将数据和时间分配给 FILETIME 结构

c++ - 如何知道创建对象时没有传入参数?

c++ - 使用 FOR 循环将数据放入 ref 数组

c++ - 如何在 mFC/C++ 中通过 HTTP post 方法发送 Zip(二进制)文件?

c++ - 如何在 C++ 中使用模板制作通用 map

C++ 为谓词和值重载 std::count_if()

c++ - 当返回类型不是指针时返回 NULL