通过 ifstream 的 Char 指针和字符串

发布于 2024-10-26 03:59:36 字数 2119 浏览 1 评论 0原文

因此,我有这个递归下降解析器,可以很好地通过命令行参数识别和使用值,但我不确定如何将其移植到从 .dat 文件读取、使用正确的字符指针、打印字符串以及处理多个字符串。

使用命令行参数的解析器:

#include <iostream>
#include <fstream>

using namespace std;

bool A(void);
bool E(void);
bool T(void);
bool F(void);
bool P(void);
bool I(void);
bool L(void);

char *c;

int main(int argc, char *argv[]){

    c = argc == 2 ? argv[1] : (char *)"";

    if (A() && *c == '\0') {
        cout << "The string \"" << argv[1] << "\" is in the language." << endl;
    }
    else {
        cout << "The string \"" << argv[1] << "\" is not in the language." << endl;
    }

    return 0;
}

bool A(void){

    if( I() )
    {
        if ( *c == '=' ){
            ++c;
            if ( E() )
            return true;
        }
    }
    return false;
}

bool E(void){

    if( T() ){
        if ( *c == '+' || *c == '-' ){
                ++c;
                return E();
        }
        return true;
    }
    return false;
}

bool F(void){

    if( P() ){
        if( *c == '^'){
            ++c;
            return F();
        }
    return true;
    }
    return false;
}

bool I(void){

    if ( *c >= 'a' && *c <= 'z'){
        ++c;
        return true;
    }
    return false;
}

bool L(void){

    if ( *c >= '0' && *c <= '9' ){
        ++c;
        return true;
    }
    return false;
}

bool P(void){

    if ( I() ){
        return true;
    }
    else
    if ( L() ){
        return true;
    }
    else
    if ( *c == '(' ){
            ++c;
            if ( E() ){
                    if ( *c == ')' ){
                        ++c;
                        return true;
                    }
            }
    }
    return false;
}

bool T(void){

    if( F() ){
        if ( *c == '*' || *c == '/' ){
                ++c;
                return T();
        }
        return true;
    }
    return false;
}

我不知道可以用什么替换 argv[1] 来打印字符串。 为了获得正确的 char 指针,我可以这样做吗?

ifstream fin("input.dat");
        while (fin >> *c)

当我尝试时,我遇到了分段错误。

So I have this recursive descent parser that works fine recognizing and using values through command line arguments but I am not sure how to port this to reading from a .dat file, using the proper char pointer, printing the string, and working for multiple strings.

Parser using command line args:

#include <iostream>
#include <fstream>

using namespace std;

bool A(void);
bool E(void);
bool T(void);
bool F(void);
bool P(void);
bool I(void);
bool L(void);

char *c;

int main(int argc, char *argv[]){

    c = argc == 2 ? argv[1] : (char *)"";

    if (A() && *c == '\0') {
        cout << "The string \"" << argv[1] << "\" is in the language." << endl;
    }
    else {
        cout << "The string \"" << argv[1] << "\" is not in the language." << endl;
    }

    return 0;
}

bool A(void){

    if( I() )
    {
        if ( *c == '=' ){
            ++c;
            if ( E() )
            return true;
        }
    }
    return false;
}

bool E(void){

    if( T() ){
        if ( *c == '+' || *c == '-' ){
                ++c;
                return E();
        }
        return true;
    }
    return false;
}

bool F(void){

    if( P() ){
        if( *c == '^'){
            ++c;
            return F();
        }
    return true;
    }
    return false;
}

bool I(void){

    if ( *c >= 'a' && *c <= 'z'){
        ++c;
        return true;
    }
    return false;
}

bool L(void){

    if ( *c >= '0' && *c <= '9' ){
        ++c;
        return true;
    }
    return false;
}

bool P(void){

    if ( I() ){
        return true;
    }
    else
    if ( L() ){
        return true;
    }
    else
    if ( *c == '(' ){
            ++c;
            if ( E() ){
                    if ( *c == ')' ){
                        ++c;
                        return true;
                    }
            }
    }
    return false;
}

bool T(void){

    if( F() ){
        if ( *c == '*' || *c == '/' ){
                ++c;
                return T();
        }
        return true;
    }
    return false;
}

I don't know what I can replace argv[1] with to print the string.
To get the proper char pointer could I just do this?

ifstream fin("input.dat");
        while (fin >> *c)

when I try that I get segmentation fault.

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

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

发布评论

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

评论(2

浊酒尽余欢 2024-11-02 03:59:38

您要求流将一个值存储到 c 指向的值所表示的内容中。相反,请考虑:

char ch;
char *c = &ch;

ifstream fin("input.dat");
while (fin >> ch) {
    // whatever
}

这不会立即出现段错误。但是,当您更改解析函数内的 c 值时,“下一次”迭代会发生不好的事情。

您需要重构程序,并从读取下一个字符的方法中抽象出读取下一个字符的意图(通过递增指针,或者从流中读取,或者任何)。

或者,您也可以将文件读入一个大的内存缓冲区,然后继续操作,就好像该缓冲区是从命令行传递的字符串一样。

You are asking the stream to store a value into what is represented by the value that c points to. Instead of that, consider:

char ch;
char *c = &ch;

ifstream fin("input.dat");
while (fin >> ch) {
    // whatever
}

This would not segfault immediately. However, bad things would happen on the "next" iteration, as you change the value of c inside the parsing functions.

You need to restructure the program and abstract the intention of reading the next character from the method of reading the next character (by incrementing a pointer, or reading from a stream, or whatever).

Or you could also read the file into one big memory buffer and then proceed as if that buffer was a string passed from the command line.

云醉月微眠 2024-11-02 03:59:38

假设您的文件是一个文本文件,每行有一个条目要解析,您可以执行以下操作:

ifstream fin("input.dat")
if (fin.is_open())
{
    std::string line;
    while (fin.good())
    {
       getline(fin, line);
       c = line.c_str();
       ... go and parse c
    }
}

更新:显然 c 是非常量,因此使用 c_str() 不会像那样工作。您有两个选择:

  1. 更改解析器以使用 std::string (使用索引指向当前字符)。
  2. 分配一些内存并将c_str()复制到其中。

第 1 种方法可能是更好的方法。

Assuming your file is a text file with one entry to parse per line you could do this:

ifstream fin("input.dat")
if (fin.is_open())
{
    std::string line;
    while (fin.good())
    {
       getline(fin, line);
       c = line.c_str();
       ... go and parse c
    }
}

Update: apparently c is non-const, so using c_str() won't work just like that. You have two options:

  1. Change your parser to work with std::string (use an index to point at the current character).
  2. Allocate some memory and copy the c_str() in there.

Number 1 is probably the better way.

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