Сравнение символьного литерала с Std :: String в C ++ - PullRequest
5 голосов
/ 30 августа 2010

Я хотел бы сравнить символьный литерал с первым элементом строки, чтобы проверить наличие комментариев в файле.Зачем использовать символ?Я хочу превратить это в функцию, которая принимает символьную переменную для комментария.Я не хочу разрешать строку, потому что хочу ограничить ее длиной до одного символа.

Имея это в виду, я предположил, что самый простой способ - обратиться к символу и передать егоФункция сравнения std :: string.Однако это дает мне непредвиденные результаты.

Мой код выглядит следующим образом:

#include <string>
#include <iostream>

int main ( int argc, char *argv[] )
{
  std::string my_string = "bob";
  char my_char1 = 'a';
  char my_char2 = 'b';

  std::cout << "STRING : " << my_string.substr(0,1) << std::endl
        << "CHAR : " << my_char1 << std::endl;
  if (my_string.substr(0,1).compare(&my_char1)==0)
    std::cout << "WOW!" << std::endl;
  else
    std::cout << "NOPE..." << std::endl;

  std::cout << "STRING : " << my_string.substr(0,1) << std::endl
        << "CHAR : " << my_char2 << std::endl;
  if (my_string.substr(0,1).compare(&my_char2)==0)
    std::cout << "WOW!" << std::endl;
  else
    std::cout << "NOPE..." << std::endl;

  std::cout << "STRING : " << my_string << std::endl
        << "STRING 2 : " << "bob" << std::endl;
  if (my_string.compare("bob")==0)
    std::cout << "WOW!" << std::endl;
  else
    std::cout << "NOPE..." << std::endl;
}

Дает мне ...

STRING : b
CHAR : a
NOPE...
STRING : b
CHAR : b
NOPE...
STRING : bob
STRING 2 : bob
WOW!

Почему функция считает, что подпрограмма-строка и характер не совпадают.Какой самый короткий способ правильно сравнить chars и std :: string vars?

(короткая попытка избежать переклассификации моего вопроса .... не стесняйтесь пропускать)
КогдаЯ говорю самое короткое, я имею в виду это из-за желания кодирования красноречия.Пожалуйста, обратите внимание, это не домашнее задание.Я кандидат наук в области химического машиностроения и занимаюсь программированием как часть независимых исследований.Один из моих последних вопросов был реклассифицирован как «домашнее задание» пользователем msw (который также сделал грубое замечание), когда я спросил об эффективности, которую я рассматривал на границе злоупотребления.Мой код может или не может быть повторно использован другими, но я пытаюсь сделать его легким для чтения и поддержки.У меня также есть странное желание сделать мой код максимально эффективным, насколько это возможно.Отсюда вопросы об эффективности и красноречии.

Ответы [ 5 ]

14 голосов
/ 30 августа 2010

Делаем это:

  if (my_string.substr(0,1).compare(&my_char2)==0)

Не сработает, потому что вы «обманываете» строку, думая, что она получает указатель на C-строку с нулевым символом в конце.Это будет иметь странные эффекты вплоть до сбоя вашей программы.Вместо этого просто используйте нормальное равенство, чтобы сравнить первый символ строки с my_char:

 if (my_string[0] == my_char)
   // do stuff
4 голосов
/ 30 августа 2010

Почему бы просто не использовать оператор индексации в вашей строке?Он вернет тип символа.

if (my_string[0] == my_char1)
3 голосов
/ 30 августа 2010

Вы можете использовать оператор [] строки, чтобы сравнить его с одним символом

// string::operator[]
#include <iostream>
#include <string>
using namespace std;

int main ()
{
    string str ("Test string");
    int i; char c = 't';
    for (i=0; i < str.length(); i++)
    {
        if (c == str[i]) {
            std::cout << "Equal at position i = " << i << std::endl;
        }
    }
    return 0;
}
1 голос
/ 30 августа 2010

Довольно стандартно, строки в c ++ заканчиваются нулем; персонажей нет. Таким образом, используя стандартный метод сравнения, вы действительно проверяете, является ли "b \ 0" == 'b'.

Я использовал это и получил желаемый результат:

if (my_string.substr(0,1).compare( 0, 1, &my_char2, 1)==0 )
    std::cout << "WOW!" << std::endl;
else
    std::cout << "NOPE..." << std::endl;

Это говорит о том, что начинайте с позиции 0 подстроки, используйте длину 1 и сравните ее с моей ссылкой на символ с длиной 1. Ссылка

1 голос
/ 30 августа 2010

Поведение первых двух вызовов для сравнения полностью зависит от того, какое случайное содержимое памяти следует за адресом каждого символа.Вы звоните basic_string::compare(const char*), и предполагается, что параметр здесь является C-String (с нулевым символом в конце), а не с одним символом.Вызов compare () сравнивает нужный символ, за которым следует все, что находится в памяти после этого символа, до следующего байта 0x00, с под рукой std :: string.

Otoh оператор << действительно имеет правильныйперегрузка для ввода символов, поэтому ваш вывод не отражает то, что вы на самом деле сравниваете здесь. </p>

Преобразуйте decls и b в const char[] a = "a";, и вы получите то, что вы хотите.

...