2010-04-22 3 views
1

Я последовал примеру код здесьНачинающий C++ Вопрос

toupper c++ example

И реализовать это в моем собственном коде следующим образом

void CharString::MakeUpper() 
{ 
char* str[strlen(m_pString)]; 
int i=0; 
str[strlen(m_pString)]=m_pString; 
char* c; 
while (str[i]) 
    { 
    c=str[i]; 
    putchar (toupper(c)); 
    i++; 
    } 
} 

Но это дает мне следующую ошибку компилятора

CharString.cpp: In member function 'void CharString::MakeUpper()': 
CharString.cpp:276: error: invalid conversion from 'char*' to 'int' 
CharString.cpp:276: error: initializing argument 1of 'int toupper(int)' 
CharString.cpp: In member function 'void CharString::MakeLower()': 

Это строка 276

putchar (toupper(c)); 

Я понимаю, что ToUpper ищет междунар в качестве параметра и возвращает Int также является то, что проблема? Если да, то как работает этот пример?

+0

Можете ли вы дать немного больше разъяснений о том, что m_pString это? Вы пытаетесь использовать один массив символов (строка C) или используете ли вы массив строк? – Eclipse

+0

Попытка заглавной буквы каждого символа в одной строке –

+6

вы ** в основном смущены ** об использовании 'char' vs.' char * '; вы, кажется, играете это на слух. Некоторое серьезное чтение С ** настоятельно рекомендуется **, прежде чем продолжить. – vladr

ответ

1

Я собираюсь перейти к предположению, что m_pString является строкой стиля C (char *). Вы делаете больше возиться, чем вам нужно.

void CharString::MakeUpper() 
{ 
    char* str = m_pString; // Since you're not modifying the string, there's no need to make a local copy, just get a pointer to the existing string. 
    while (*str) // You can use the string pointer as an iterator over the individual chars 
    { 
     putchar (toupper(*str)); // Dereference the pointer to get each char. 
     str++; // Move to the next char (you can merge this into the previous line if so desired, but there's no need. 
    } 
} 

В примере, который вы цитируете, причина, по которой он работает, объясняется тем, как объявляются переменные.

int main() 
{ 
    int i=0; 
    char str[]="Test String.\n"; // This is a compile time string literal, so it's ok to initialize the array with it. Also, it's an array of `char`s not `char*`s. 
    char c; // Note that this is also a `char`, not a `char *` 
    while (str[i]) 
    { 
    c=str[i]; 
    putchar (toupper(c)); 
    i++; 
    } 
    return 0; 
} 

Из-за ошибок склонных способов использования строк C, лучше всего это станд :: строка:

void CharString::MakeUpper() 
{ 
    string str(m_pString); 
    transform(str.begin(), str.end(), ostream_iterator<char>(cout), &toupper); 
} 
+0

Спасибо Eclipse, отличное объяснение и 100% правильно –

+0

На самом деле все было неправильно - 'while (str)' должно быть 'while (* str)'. Вы не продвигаетесь до тех пор, пока указатель не будет «NULL», вы продвигаетесь до тех пор, пока указанный символ не будет '' \ 0''. См. Исправленную версию выше. Тем более, что вам нужно держаться подальше от строки C и использовать 'std :: string'. – Eclipse

+0

Использование string ввело целый набор новых ошибок компилятора :(Я включил , но я получаю строку не определены ошибки –

1

Существует не встроенное преобразование от char * к int, поэтому возникла ошибка. Поскольку вы пытаетесь загладить символ, вам нужно разыменовать указатель.

putchar(toupper(*c));

+1

@Matt, это только верхушка айсберга. Он использует 'char *' везде, где он должен был использовать 'char'. – vladr

2

Вы должны кормить ToUpper() Int (или символ), а не символ *, который, как вы объявили с.

попробовать:

char c; 

Кроме того,

char* str[strlen(m_pString)]; 

является массивом указателей на символы, а не только одна строка.

Эта линия:

str[strlen(m_pString)]=m_pString; 

является отнесением к плохому указателю, то, так как не было никакого распределения.

4

Кроме того,

char* str[strlen(m_pString)]; 
int i=0; 
str[strlen(m_pString)]=m_pString; 

не является допустимым C++ - массивы должны быть рассчитаны с помощью компиляции константы времени - это функция C99. И я действительно не думаю, что код будет делать то, что вы хотите, даже если это было законно, поскольку вы, кажется, обращаетесь к одному из концов конца массива. Было бы удобно, если бы вы разместили полное определение класса.

+0

массивы должны быть рассчитаны с использованием констант времени компиляции - интересно. Это происходит в новой спецификации C++? – WhirlWind

+1

@WhirlWind Это всегда было так. Он не изменяется в C++ 0x. – 2010-04-22 16:27:27

+2

@WhirlWind: Так C++ всегда был и как C был до C99. Не было никакого стимула изменить это в предстоящем стандарте C++, потому что 'std :: vector <>' будет обрабатывать переменную длину и делать больше. –

3

Я не думаю, что ваш код делает то, что вы хотите, и на самом деле, если он скомпилирован, он взорвется.



char* str[strlen(m_pString)]; // you've made an array of X C strings where 
           // X is the length of your original string. 
int i=0; 


str[strlen(m_pString)]=m_pString; // You've attempted to assign the C string in your array 
            // at location X to point at you m_pString. X is the 
            // same X as before and so is 1 past the end of the array 
            // This is a buffer overrun. 

Я думаю, что вы действительно хотели сделать, это скопировать содержимое m_pString в str. Вы бы сделать это так:



char * str = new char[strlen(m_pString)]; 
memcpy(str, m_pString); // I may have the operands reversed, see the docs. 

Чем проще способ сделать это, хотя это прекратить использование строк C и использовать C++ строки:



std::string str = m_pString; 

Есть еще вопросы, но это должно вы направляете вас в правильное направление.

Смежные вопросы