c++ - 在 C++ 中正确处理来自 argv 的字符串中的转义序列

标签 c++ escaping special-characters

我正在编写一个更大的程序,它在可执行文件之后从命令行获取参数。一些参数应该在选项的等号之后传递。例如,默认情况下,日志的输出是一个逗号分隔的 vector ,但如果用户想将分隔符更改为句号或其他东西而不是逗号,他们可能会给出如下参数:

./main --separator="."

这很好用,但如果用户希望分隔符是一个特殊字符(例如:制表符),他们可能希望通过以下方式之一传递转义序列:

./main --separator="\t"
./main --separator='\t'
./main --separator=\t

它没有按照我想要的方式运行(将\t 解释为制表符)而是打印出写入的字符串(没有引号,没有引号它只打印“t”)。我试过使用双斜杠,但我想我可能只是错误地处理了这个问题,我什至不确定如何正确地提出问题(我试过搜索)。

我在此处的虚拟示例中重现了该问题:

#include <string>
#include <iostream>
#include <cstdio>

// Pull the string value after the equals sign
std::string get_option( std::string input );
// Verify that the input is a valid option
bool is_valid_option( std::string input );

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

    if ( argc != 2 )
    {
        std::cerr << "Takes exactly two arguments.  You gave " << argc << "." << std::endl;

        exit( -1 );
    }

    // Convert from char* to string

    std::string arg ( argv[1] );

    if ( !is_valid_option( arg ) )
    {
        std::cerr << "Argument " << arg << " is not a valid option of the form --<argument>=<option>." << std::endl;

        exit( -2 );
    }

    std::cout << "You entered: " << arg << std::endl;
    std::cout << "The option you wanted to use is: " << get_option( arg ) << "."  << std::endl;

    return 0;
}

std::string get_option( std::string input )
{
    int index = input.find( '=' );
    std::string opt = input.substr( index + 1 ); // We want everything after the '='
    return opt;
}

bool is_valid_option( std::string input )
{
    int equals_index = input.find('=');

    return ( equals_index != std::string::npos && equals_index < input.length() - 1 );
}

我这样编译:

g++ -std=c++11 dummy.cpp -o dummy

使用以下命令,它会产生以下输出。

带双引号:

/dummy --option="\t"
You entered: --option=\t
The option you wanted to use is: \t.

单引号:

./dummy --option='\t'
You entered: --option=\t
The option you wanted to use is: \t.

没有引号:

./dummy --option=\t
You entered: --option=t
The option you wanted to use is: t.

我的问题是:有没有办法指定它应该将子字符串\t 解释为制表符(或其他转义序列)而不是字符串文字“\t”?我可以手动解析它,但我试图避免在我可能只是遗漏一些小东西时重新发明轮子。

非常感谢您的时间和答复。这件事太简单了,让我抓狂,我不知道如何快速简单地修复它。

最佳答案

转义序列已经从您使用的 shell 中解析出来,并相应地传递给您的命令行参数数组 argv

正如您所注意到的,只有引用的版本才能让您检测到 "\\t" 字符串已被解析并传递给您的 main()
由于大多数 shell 可能只是将 真正的 TAB 字符 作为空格跳过,因此您永远不会在命令行参数中看到它。

但如前所述,这主要是 shell 如何解释命令行的问题,以及程序调用参数中剩下的内容,而不是如何使用 c++ 或 c 处理它。

My question is: Is there a way to specify that it should interpret the substring \t as a tab character (or other escape sequences) rather than the string literal "\t"? I could parse it manually, but I'm trying to avoid re-inventing the wheel when I might just be missing something small.

您实际上需要扫描字符串文字

"\\t"

在 C++ 代码中。

关于c++ - 在 C++ 中正确处理来自 argv 的字符串中的转义序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38209764/

相关文章:

sql - 如何返回引号内的字符串

sql - 特殊字符VT是什么?我需要从 MS SQL 替换它

c++ - 访问冲突读取位置 (Visual Studio C++)

c++ - 使用 istringstream 丢失随机字符

带有 clang 的 C++ 11 线程

zend-framework - Zend Framework 中的 html_entity_decode 等效项

html - JSON 转义空格字符

ruby-on-rails - 为 Rails 上的连接、限制、选择等(不是条件)的 SQL 片段安全地转义字符串

C++ 元素访问无法正常工作?

bash 发现将 * 视为 *