使用 getline() 在单引号中读取

Read in Single Quote using getline()

本文关键字:单引号 读取 getline 使用      更新时间:2023-10-16

我正在做UVa问题10082,我正在尝试读取一些示例输入来测试我的解决方案。但是,当我阅读文本'''CCC时,它会输出;;XXX.请注意,只有 2 个分号,而应该有 3 个分号,因为输入中有 3 个单引号。为什么 getline() 忽略第一个单引号?

这是我的代码:

#include <iostream>
#include <string>
using namespace std;
char mapToWertyu(char c)
{
    char newC = c;
    char wertyu[] = {'1','2','3','4','5','6','7','8','9','0','-','=',
                     'Q','W','E','R','T','Y','U','I','O','P','[',']','',
                     'A','S','D','F','G','H','J','K','L',';',''',
                     'Z','X','C','V','B','N','M',',','.','/'};
    char qwerty[] = {'~','1','2','3','4','5','6','7','8','9','0','-','=',
                     'Q','W','E','R','T','Y','U','I','O','P','[',']','',
                     'A','S','D','F','G','H','J','K','L',';',''',
                     'Z','X','C','V','B','N','M',',','.','/'};
    if(c=='A' || c=='Q' || c=='Z')
        return c;
    for(int i = 0; i < 47; ++i)
    {
        if(wertyu[i]==c)
        {
            newC = qwerty[i];
            break;
        }
    }
    return newC;
}
int main()
{
    string input;
    while(cin.peek()!=-1)
    {
        getline(cin,input);
        for(int i = 0; i < input.length(); ++i)
        {
            if(input[i]!='')
                cout << mapToWertyu(input[i]);
        }
        cin.ignore(1,'n');
        cout << endl;
    }
    return 0;
}

因为你告诉它。 你认为std::cin.ignore( 1, 'n' )应该怎么做,如果不忽略一个角色。 std::getline提取'n'字符,即使它没有将其放入字符串。

对于其余部分,您没有正确执行输入。 对于初学者,std::cin.peek()将在范围[0...UCHAR_MAX]EOFEOF通常被定义为 -1,但这肯定不能保证。 但更一般地说:为什么不使用通常的成语:

while ( std::getline( std::cin, input ) ) {
    //  ...
}

每次您都以mapToWertyu构造数组叫它。 这绝对不是你想做的。 你可以只使用一个静态数组,直接由字符索引,错误 这确实使程序依赖于编码。 自但是,请使用两个数组:

static char const wertyu[] = { ... };
static char const qwerty[] = { ... };
char const* pos = std::find( std::begin( wertyu ), std::end( wertyu ), c );
return pos == std::end( wertyu )
    ? c
    : qwerty[ pos - std::begin( wertyu ) ];

以更简单的方式解决问题。 (而且没有需要特殊情况'A''Q''Z'。 如果你不想要要对它们进行转码,只是不要将它们放在表中。

或。。。

struct Map
{
    char from;
    char to;
};
static Map const map[] =
{
    { '1', '~' },
    { '2', '1' },
    //  ...
};
Map const* pos = std::find_if( std::begin( map ), std::end( map ),
                    []( char ch ) { return c == ch; } );
return pos == std::end( map )
    ? c
    : pos->to;

这样做的好处是使精确的映射可见。

或者,如果您 100% 确定永远不必担心线程:

struct Map
{
    char from;
    char to;
};
static Map map[] =
{
    { '1', '~' },
    { '2', '1' },
    //  ...
    {  0,   0  }
};
Map* sentinal = std::end( map ) - 1;
sentinal->to = sentinal->from = c;
Map const* pos = std::find_if( std::begin( map ), std::end( map ),
                    []( Map const& entry ) { return c == entry.from; } );
return pos->to;

通过插入哨兵,您可以确定该条目将被发现。

或者,您可以对地图进行排序,并使用std::lower_bound .

另外,为什么在映射时调用函数mapToWertyu去奎尔蒂?