首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++写入stringstream不能正常工作

C++写入stringstream不能正常工作
EN

Stack Overflow用户
提问于 2021-02-17 19:03:03
回答 2查看 79关注 0票数 0

这些天我一直在为CHIP-8做一个汇编器,今天我试着实现操作码的参数以使其正常工作。但是,当我必须编写2个参数来完成操作码时,我有以下代码:

代码语言:javascript
复制
// Chip8Instruction is a struct I've made that holds the final machine code to be written, the mnemonic,
// the argument count and the position for each argument in hex
void writeTwoArguments(Chip8Instruction instruction, const std::string& line, int lineNum, const std::string& romName) {
    unsigned int arg1;
    unsigned int arg2;
    
    std::string remainingLine = line;
    std::string testStr;

    std::stringstream stringStream;


    // Arguments are comma and then space separated, assume I give 3, FF
    std::string::size_type commaPos = line.find(',');
    
    if (commaPos != std::string::npos) {
        stringStream << std::hex << remainingLine.substr(0, commaPos); // This writes 3, like it should
        testStr = stringStream.str(); // Holds "3", like it should
        stringStream >> arg1; // This holds 0x3, like it should
        stringStream.str("");

        remainingLine.erase(0, commaPos+2); // FF remains, like it should
        stringStream << std::hex << remainingLine;
        testStr = stringStream.str(); // This holds nothing but it should have "FF", if I don't empty the stream it holds "3" from before
        stringStream >> arg2; // This also holds nothing but it should have 0xFF, holds 0x3 if not empty stream

        instruction.machineCode = instruction.start + (arg1 * instruction.arg1Pos) + (arg2 * instruction.arg2Pos);
    }

    writeMultipleDigitsToROM(romName, instruction.machineCode, lineNum);

}

最小可重复性示例:

代码语言:javascript
复制
#include <iostream>
#include <sstream>

int main() {
   std::string line = "3, FF";

   std::stringstream stringStream;

   unsigned int int1;
   unsigned int int2;

   // Get position of comma
   std::string::size_type commaPos = line.find(',');

   // Get everything up to the comma
   stringStream << std::hex << line.substr(0, commaPos);
   stringStream >> int1; // This holds 0x3, like it should
   stringStream.str(""); 
   line.erase(0, commaPos+2); // "FF" remains, like it should
   stringStream << std::hex << line;
   stringStream >> int2; // This is empty but should be 0xFF
   
}

正如代码注释所描述的,保留的值要么是错误的,要么是过时的。问题可能是什么,为什么,以及我如何解决它?

非常感谢您的帮助,谢谢!

EN

回答 2

Stack Overflow用户

发布于 2021-02-17 19:39:21

我试着用下面的代码解决这个问题:

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int main() {
    string input = "3, FF";
    stringstream ss;
    ss << input.substr(0, 1);
    cout << ss.str() << endl;
    input.erase(0, 3);
    ss.str("");
    cout << input << endl;
    ss << std::hex << input;
    cout << ss.str() << endl;

    return 0;
}

然而,它似乎在我这一端工作正常。不知道有什么不同,对不起,除非我在输入格式上犯了错误。顺便说一句,我建议不要提取到字符串流,而是通过将输入包装在字符串流中来提取,如下所示:

代码语言:javascript
复制
int arg1, arg2;
string comma;
stringstream ss(input);
ss >> std::hex >> arg1 >> comma >> arg2;
cout << arg1 << endl;
cout << arg2 << endl;

更好的是,你可以为你的类型重载流提取操作符operator>>,所以它可能是这样的:

代码语言:javascript
复制
Chip8Instruction c;
ss >> c;
// do stuff now that c is filled in

您可以通过声明如下内容来实现此目的:

代码语言:javascript
复制
istream& operator>>(istream& in, Chip8Instruction& out) {
   // where your code to parse the string could go
}

抱歉,我不能帮助解决实际的解析问题,但我不清楚我做了什么与您不同的事情。

票数 2
EN

Stack Overflow用户

发布于 2021-02-17 20:08:30

首先:std::hex改变了整数打印或扫描的方式。它对line没有影响-- line是一个字符串。stringStream << std::hex << line;stringStream << line;相同。

执行stringStream >> int1;之后,在stringStream中设置eof位。要扫描任何其他内容,您必须先清除它。请研究如何重置stringstream

要读取hex数字,你必须告诉你的流你想要读取一个十六进制数字。F不是数字!

但总体而言,它的用法很奇怪--只要从stringstream中读取数据,它就是从字面上读取数据的东西。忘记你的string吧--在stream上工作。记住要处理错误。我可以看到:

代码语言:javascript
复制
#include <iostream>
#include <sstream>
#include <iomanip>

int main() {
    std::string line = "3, FF";

    std::istringstream ss(line);
    unsigned int int1;
    unsigned int int2;
    if (!(
            (ss >> std::dec >> int1) &&
            ss.get() == ',' &&
            (ss >> std::hex >> int2)
            )) {
        std::cerr << "read failed\n";
        abort();
    }
    std::cout << int1 << " " << int2 << "\n";
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66240640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档