【问题标题】:Weird character when displaying data from .dat file in c++在 C++ 中显示来自 .dat 文件的数据时出现奇怪的字符
【发布时间】:2021-11-26 06:08:42
【问题描述】:

我有一个ipk.dat 文件,其中包含学生姓名和他们的 GPA,用分号分隔。我正在尝试显示 GPA 大于 3 的学生的姓名,但我在控制台中得到了类似这样奇怪字符的输出。

Hidayat Sari            3.60 
Susila Buana            3.27 
Krisna Sari             3.66 
Taufik Fatimah          3.38 
Bachtiar Darma          3.70 
Yohanes Anwar           3.93 
Harun Ratna             3.48 
Mega Zulfikar           3.32 
Zulfikar Abdul          3.50 
Rahman Nirmala          3.37 
Amir Cinta              3.30 
Firdaus Latifah         3.16 
Annisa Ali              3.65 
Eka Yuliana             3.14

这是我的代码:

#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;

int main() {
    ifstream inGPA;
    string studentGPA;
    string studentName;
    inGPA.open("ipk.dat");

    if (inGPA.is_open()) {
        string line;
        while (getline(inGPA, line)) {
            stringstream ss(line);
            getline(ss, studentName, ';');
            getline(ss, studentGPA);

            if ( stod(studentGPA) >= 3.0) {
                cout << studentName << "     \t" << studentGPA << endl;
            }
        }
    }
    return 0;
}

这是 ipk.dat 文件的内部。这个文件的编码是 UTF-8。

如何解决这个奇怪的字符问题?

【问题讨论】:

  • 输入文件中的“空格”实际上是“空格”还是一些看起来像“空格”的特殊字符?我会尝试手动编辑 dat 文件,删除名称之间的“空格”并在那里显式添加一个空格,看看是否能解决问题
  • @DedeKurniawan 您能否复制/粘贴您问题中的文本文件,以便我们自己测试而不是发布文本文件的图片。
  • 还可以在十六进制编辑器中查看输入文件,以确切了解“空格”字符是什么。
  • @PepijnKramer 啊,我明白了。非常感谢您的解决方案。它修复了。
  • 空格是UTF-8编码的U+00A0,也称为不间断空格。

标签: c++ fstream ifstream


【解决方案1】:

不间断的空格可能是不需要的输入,但如果你的名字包含非 ASCII 字符,你也会遇到同样的问题。

这里的部分问题是您的终端不知道您正在发送 UTF-8 编码的字符。

如果您使用的是 Windows,可以参考this question
基本思路是先设置终端理解UTF-8:

#include <Windows.h>

int main() {
    SetConsoleOutputCP(CP_UTF8); // set output to UTF-8
    // your code
}

这将正常打印您的不间断空格字符。

注意:此更改不仅会持续执行您的程序。
如果您在修复后运行未修复的程序,该程序似乎可以运行,直到您在新的终端中运行它。

【讨论】:

    【解决方案2】:

    由于您已经解决了您的问题(似乎与输入文件而不是程序有关),我想对͟r͟e͟m͟o͟v͟e͟͟t͟h͟e͟͟r͟e͟d͟u͟n͟d͟a͟n͟c͟i͟e͟s͟提出一项修改。特别是,您不需要

    //no need for these three statements
    stringstream ss(line);
    getline(ss, studentName, ';');
    getline(ss, studentGPA);
    

    在您的程序中。相反,您可以直接在studentNamestudentGPA 上使用getline,如下所示。

    #include <iostream>
    #include <fstream>
    #include <sstream>
    using namespace std;
    
    int main() {
        ifstream inGPA;
        string studentGPA;
        string studentName;
        inGPA.open("input.txt");
    
        if (inGPA.is_open()) {
            string line;
            //just getline directly into variables studentName and studentGPA
            while (getline(inGPA, studentName, ';'), getline(inGPA, studentGPA)) {
    
                if ( stod(studentGPA) >= 3.0) {
                    cout << studentName << "     \t" << studentGPA << endl;
                }
            }
        }
        return 0;
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 2010-12-23
      相关资源
      最近更新 更多