C ++ - ошибка E2285: не удалось найти совпадение для 'tolower (char *)' в функции parseInput (fstream &) - PullRequest
6 голосов
/ 06 декабря 2010

С учетом следующего кода:

 void parseInput(fstream &inputFile) {
        const int LENGTH = 81;
        char line[LENGTH];

        while(!inputFile.fail()) {
            inputFile.getline(line,LENGTH);
            line = tolower(line);
            cout << line << endl;
        }
    }

после компиляции я получаю эту ошибку:

Ошибка E2285: не удалось найти совпадение для 'tolower (char *)' в функция parseInput (fstream &)

Я знаю, что он возвращает int, но не int []. Означает ли это, что вместо использования getline я должен получить вводимый символ в символ? Есть ли способ конвертировать всю строку в нижнюю? Заранее спасибо всем за помощь!

Ответы [ 6 ]

6 голосов
/ 06 декабря 2010

Привет, параметр ввода функции tolower должен быть char, а не char *, но если вы используете std, вы можете использовать string и std: transform, чтобы сделать строку строчной буквой

std::string data = “MyStrData”; 
std::transform(data.begin(), data.end(), data.begin(), ::tolower);
3 голосов
/ 06 декабря 2010

Автономная функция tolower принимает только один int, и int должен быть строго неотрицательным или EOF, иначе поведение не определено. Существует другая версия tolower, которая, однако, является шаблоном. Оба эти факта затрудняют использование их с transform легко и безопасно.

C ++ также предоставляет tolower в его ctype фасете, который вы можете использовать здесь

std::ctype<char> const& c = std::use_facet< std::ctype<char> >(std::locale());
c.tolower(line, line + std::strlen(line));

Однако весь код показывает, что вы не знакомы с массивами и точками, поэтому, возможно, вам следует начать использовать std::string и простые в использовании алгоритмы? Посмотрите на boost::string_algo ' преобразования регистра .

1 голос
/ 06 декабря 2010

Хм, три ответа здесь удалось использовать tolower неправильно .

Его аргумент должен быть неотрицательным или специальным значением EOF, в противном случае неопределенное поведение.Если все, что у вас есть, это символы ASCII, то все коды будут неотрицательными, поэтому в этом особом случае его можно использовать напрямую.Но если есть какой-либо не-ASCII символ, как в норвежском "blåbærsyltetøy" (черничное варенье), то эти коды, скорее всего, отрицательны, поэтому необходимо привести аргумент к типу без знака char.в этом случае языковой стандарт C должен быть установлен на соответствующий языковой стандарт.

Например, вы можете установить его в языковой стандарт пользователя по умолчанию, который обозначается пустой строкой в ​​качестве аргумента setlocale.

Пример:

#include <iostream>
#include <string>           // std::string
#include <ctype.h>          // ::tolower
#include <locale.h>         // ::setlocale
#include <stddef.h>         // ::ptrdiff_t

typedef unsigned char   UChar;
typedef ptrdiff_t       Size;
typedef Size            Index;

char toLowerCase( char c )
{
    return char( ::tolower( UChar( c ) ) );     // Cast to unsigned important.
}

std::string toLowerCase( std::string const& s )
{
    using namespace std;
    Size const      n   = s.length();
    std::string     result( n, '\0' );

    for( Index i = 0;  i < n;  ++i )
    {
        result[i] = toLowerCase( s[i] );
    }
    return result;
}

int main()
{
    using namespace std;
    setlocale( LC_ALL, "" );                    // Setting locale important.
    cout << toLowerCase( "SARAH CONNER LIKES BLÅBÆRSYLTETØY" ) << endl;
}

Пример того, как вместо этого сделать это, используя std::transform:

#include <iostream>
#include <algorithm>        // std::transform
#include <functional>       // std::ptr_fun
#include <string>           // std::string
#include <ctype.h>          // ::tolower
#include <locale.h>         // ::setlocale
#include <stddef.h>         // ::ptrdiff_t

typedef unsigned char   UChar;

char toLowerCase( char c )
{
    return char( ::tolower( UChar( c ) ) );     // Cast to unsigned important.
}

std::string toLowerCase( std::string const& s )
{
    using namespace std;
    string          result( s.length(), '\0' );

    transform( s.begin(), s.end(), result.begin(), ptr_fun<char>( toLowerCase ) );
    return result;
}

int main()
{
    using namespace std;
    setlocale( LC_ALL, "" );                    // Setting locale important.
    cout << toLowerCase( "SARAH CONNER LIKES BLÅBÆRSYLTETØY" ) << endl;
}

Пример использования языка локали уровня C ++ вместо языка C см. В Johannes 'ответ.

Приветствия и hth.,

0 голосов
/ 06 декабря 2010

да и нет.Вы можете получить целую строку, но печатать ее char после char (и используя tolower), используя цикл for.

0 голосов
/ 06 декабря 2010

tolower() работают только с одним персонажем одновременно. Вы должны сделать что-то вроде

for(int i = 0; i < LENGTH; ++i)
  line[i] = tolower(line[i]);
0 голосов
/ 06 декабря 2010

Вы можете просто выполнить следующий цикл, чтобы преобразовать строку, символ за символом, в нижний регистр:

const int lineLen = strlen( line );
for ( int i = 0; i < lineLen; i++ )
{
     line[i] = static_cast< char >( ::tolower( static_cast< unsigned char >( line[i] ) ) );
}

Редактировать: , кроме того, следующий код еще проще (при условии, что строка завершена нулем).

_strlwr( line );
...