std::stringstream 从字符串中读取 int 和字符串

发布于 2024-08-14 11:16:49 字数 1912 浏览 8 评论 0原文

我正在用 C++ 编程,我不确定如何实现以下目标:

我将文件流复制到内存(因为我被要求这样做,我更喜欢从流中读取),然后尝试访问其值将它们存储到字符串和 int 变量中。

这是创建一个解释器。我将尝试解释的代码是(即):

10 PRINT A
20 GOTO 10

这只是一个快速示例代码。现在,这些值将首先存储在“映射”结构中,并在稍后所有内容都将被“解释”时访问。 要存储的值是:

int lnum // 行号

string cmd // 命令(PRINT 和 GOTO)

string exp // 表达式(本例中为 A 和 10,但可以保存 (a*b)-c 等表达式)

问题是给定以下代码,如何访问这些值并将它们存储在内存中? 此外,exp 字符串的大小可变(可以只是变量或表达式),因此我不确定如何读取它并将其存储在字符串中。

代码:


#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <map>
#include <sstream>

using namespace std;

 #include "main.hh"


int main () 
{
    int lenght;
    char *buffer;

// get file directory
    string dir;
    cout << "Please drag and drop here the file to interpret: ";
    getline (cin,dir);
    cout << "Thank you.\n";
    cout << "Please wait while your file is being interpreted.\n \n";

// Open File
    ifstream p_prog;
    p_prog.open (dir.c_str());

// Get file size
    p_prog.seekg (0, ios::end);
    lenght = p_prog.tellg();
    p_prog.seekg(0, ios::beg);

// Create buffer and copy stream to it
    buffer = new char[lenght];
    p_prog.read (buffer,lenght);
    p_prog.close();

// Define map<int, char>
    map<int, string> program;
    map<int, string>::iterator iter;


/***** Read File *****/
    int lnum; // line number
    string cmd; // store command (goto, let, etc...)
    string exp; // to be subst with expr. type inst.

//  this is what I had in mind but not sure how to use it properly
//  std::stringstream buffer;
//  buffer >> lnum >> cmd >> exp;

    program [lnum] = cmd; // store values in map




// free memory from buffer, out of scope
    delete[] buffer;
    return 0;
}

我希望这是清楚的。

感谢您的帮助。

瓦莱里奥

I am programming in C++ and I'm not sure how to achieve the following:

I am copying a file stream to memory (because I was asked to, I'd prefer reading from stream), and and then trying to access its values to store them into strings and int variables.

This is to create an interpreter. The code I will try to interpret is (ie):

10 PRINT A
20 GOTO 10

This is just a quick example code. Now the values will be stored in a "map" structure at first and accessed later when everything will be "interpreted".
The values to be stored are:

int lnum // line number

string cmd // command (PRINT and GOTO)

string exp // expression (A and 10 in this case but could hold expressions like (a*b)-c )

question is given the following code, how do I access those values and store them in memory?
Also the exp string is of variable size (can be just a variable or an expression) so I am not sure how to read that and store it in the string.

code:


#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <map>
#include <sstream>

using namespace std;

 #include "main.hh"


int main () 
{
    int lenght;
    char *buffer;

// get file directory
    string dir;
    cout << "Please drag and drop here the file to interpret: ";
    getline (cin,dir);
    cout << "Thank you.\n";
    cout << "Please wait while your file is being interpreted.\n \n";

// Open File
    ifstream p_prog;
    p_prog.open (dir.c_str());

// Get file size
    p_prog.seekg (0, ios::end);
    lenght = p_prog.tellg();
    p_prog.seekg(0, ios::beg);

// Create buffer and copy stream to it
    buffer = new char[lenght];
    p_prog.read (buffer,lenght);
    p_prog.close();

// Define map<int, char>
    map<int, string> program;
    map<int, string>::iterator iter;


/***** Read File *****/
    int lnum; // line number
    string cmd; // store command (goto, let, etc...)
    string exp; // to be subst with expr. type inst.

//  this is what I had in mind but not sure how to use it properly
//  std::stringstream buffer;
//  buffer >> lnum >> cmd >> exp;

    program [lnum] = cmd; // store values in map




// free memory from buffer, out of scope
    delete[] buffer;
    return 0;
}

I hope this is clear.

Thank you for your help.

Valerio

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不…忘初心 2024-08-21 11:16:49

您可以使用 std::stringstream 来拉取令牌,假设您已经知道类型。

对于解释器,我强烈建议使用实际的解析器,而不是编写自己的解析器。 Boost 的 XPressive 库或 ANTLR 工作得很好。您可以在解析语法时使用语义操作来构建解释器原语或简单地构建 AST。

另一种选择是 Flex & 野牛。基本上,这些都是解析预定义语法的工具。您可以自己构建,但要做好遭受挫折的准备。递归地平衡括号或强制执行运算顺序(例如,先除后乘)并非易事。

原始C++解析方法如下:


#include <sstream>
#include <string>

// ... //

istringstream iss(buffer);
int a, b;
string c, d;

iss >> a;
iss >> b;
iss >> c;
iss >> d;

You can use a std::stringstream to pull tokens, assuming that you already know the type.

For an interpreter, I'd highly recommend using an actual parser rather than writing your own. Boost's XPressive library or ANTLR work quite well. You can build your interpreter primitives using semantic actions as you parse the grammar or simply build an AST.

Another option would be Flex & Bison. Basically, these are all tools for parsing pre-defined grammars. You can build your own, but prepare for frustration. Recursively balancing parentheses or enforcing order of operations (divide before multiply, for example) isn't trivial.

The raw C++ parsing method follows:


#include <sstream>
#include <string>

// ... //

istringstream iss(buffer);
int a, b;
string c, d;

iss >> a;
iss >> b;
iss >> c;
iss >> d;

や三分注定 2024-08-21 11:16:49

完成此类操作的方法(尤其是您提到的算术表达式部分)是:

  • 编写一些代码来确定标记的结束和开始位置。例如 5+ 将被称为令牌。您可以扫描文本中的这些分隔符或常见分隔符(例如空格)。
  • 写下您正在解析的语言的语法。例如,您可以编写:
 表达式 ->价值
    表达式->表情+表情
    表达式->表达式 * 表达式
    表达式->函数(表达式)
    表达式-> ( 表达 )

然后,根据这个语法,您将编写一些将表达式的标记解析为树的东西。

所以你可能有一棵看起来像这样的树(请原谅 ASCII 艺术)

 +
          /\
         5 *
              /\
             x 3

其中这表示表达式 5 + (x * 3)。通过在树结构中使用它,可以很容易地计算代码中的表达式:您可以递归地下降树,以子节点作为参数执行操作。

请参阅以下维基百科文章:

或咨询您当地的计算机科学部门。 :-)

还有一些工具可以根据语法为您生成这些解析器。您可以搜索“解析器生成器”。

The way something like this can be done (especially the arithmetic expression part that you alluded to) is:

  • Write some code that determines where a token ends and begins. For example 5 or + would be called a token. You might scan the text for these, or common separators such as whitespace.
  • Write up the grammar of the language you're parsing. For example you might write:
    expression -> value
    expression -> expression + expression
    expression -> expression * expression
    expression -> function ( expression )
    expression -> ( expression )

Then based on this grammar you would write something that parses tokens of expressions into trees.

So you might have a tree that looks like this (pardon the ASCII art)

            +
          /   \
         5     *
              / \
             x   3

Where this represents the expression 5 + (x * 3). By having this in a tree structure it is really easy to evaluate expressions in your code: you can recursively descend the tree, performing the operations with the child nodes as arguments.

See the following Wikipedia articles:

Or consult your local computer science department. :-)

There are also tools that will generate these parsers for you based on a grammar. You can do a search for "parser generator".

病毒体 2024-08-21 11:16:49

不要显式使用向量来动态分配缓冲区。
这使得内存管理变得隐式。

// Create buffer and copy stream to it   
std::vector<char>   buffer(lenght);
p_prog.read (&buffer[0],lenght);
p_prog.close();

就我个人而言,我不会明确使用 close() (除非我想捕获异常)。只需在某个范围内打开一个文件,当文件超出范围时,析构函数就会关闭该文件。

Don't do the dynamic allocation of the buffer explicitly use a vector.
This makes memory management implicit.

// Create buffer and copy stream to it   
std::vector<char>   buffer(lenght);
p_prog.read (&buffer[0],lenght);
p_prog.close();

Personally I don't explicitly use close() (unless I want to catch an exception). Just open a file in a scope that will cause the destructor to close the file when it goes out of scope.

萌︼了一个春 2024-08-21 11:16:49

这可能会有所帮助:

http://oopweb .com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html

特别是第 7.3 节。

您可能最好只是<<'输入线路而不是寻找和字符缓冲区路线。

This might be of help:

http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html

Especially section 7.3.

You might be better off just <<'ing the lines in rather than the seeking and charbuffer route.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文