Неправильно использовать верхний? Рабочий код, пока я не ввел toupper

#c #toupper

#c #toupper

Вопрос:

Моя программа работала так, как и предполагалось, пока я не добавил часть toupper в свою программу. Я пытался просмотреть свой код ошибки, но это не очень помогает. Ошибки:

не ожидается совпадения функции для вызова 2 аргументов, один предоставлен

Итак, я знаю, что ошибка в этих двух операторах в моем цикле while. Что я сделал не так?

Я хочу создать имя, подобное

джон Браун перейти к Джону Брауну

 #include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

int main(){

  string firstname[5];
  string lastname[5];
  ifstream fin( "data_names.txt" );
  if (!fin) {
    cout << "There is no file" << endl;
  }
  int i = 0;
  while( i < 5 amp;amp; (fin >> firstname[i]) amp;amp; (fin >> lastname[i]) ) {
    firstname[0] = toupper(firstname[0]);
    lastname[0] = toupper(lastname[0]);
    i  ;
  }
  cout << firstname[0] << " " << lastname [0] << endl;
  cout << firstname[1] << " " << lastname [1] << endl;
  cout << firstname[2] << " " << lastname [2] << endl;
  cout << firstname[3] << " " << lastname [3] << endl;
  cout << firstname[4] << " " << lastname [4] << endl;

  return 0;
}
  

Комментарии:

1. На какую строку указывает ошибка?

2. toupper ожидает int , что вы передаете ему string toupper документацию .

3. toupper работает с одним символом за раз. Если вы хотите увеличить всю строку, вам нужно создать цикл, который проходит через строку, применяемую toupper к каждому символу

4. @M.M Я хочу использовать только прописные эти две буквы. Как мне выделить эти символы строки и сделать это правильно?

5. @JOHNSMITH8338 какие две буквы?

Ответ №1:

std::toupper работает с отдельными символами, но вы пытаетесь применить его к строкам. Помимо добавления #include <cctype> , вам необходимо изменить тело вашего while цикла:

 firstname[i][0] = toupper(firstname[i][0]);
lastname[i][0] = toupper(lastname[i][0]);
i  ;
  

Тогда он должен работать так, как ожидалось. Живая демонстрация здесь

Как любезно указал М.М. В комментариях, вы также должны проверить, что ваши строки не пустые, прежде чем обращаться к их первым символам, т. Е. Что-то вроде

 if (!firstname[i].empty()) firstname[i][0] = toupper(...);
  

настоятельно рекомендуется.

Имейте в виду, вам, вероятно, понадобится более сложная логика, если вы получите такие имена, как McDonald 🙂

Комментарии:

1. Технически это должно быть либо toupper( (unsigned char)firstname[i][0] ); (с включенным cctype), либо toupper( firstname[i][0], std::locale() ) . Также было бы неплохо проверить, что строка не пуста для выполнения [0]

2. @M.M Я согласен. Код вопроса мог бы выиграть от гораздо более общего обзора.

3. @mindriot Извините, я пропустил часть о включении cctype .

4. @juanchopanza на самом деле, похоже cctype , что это даже не является строго необходимым ( демо ), похоже, что он все равно попадает в один из других заголовков.

5. @mindriot Да, но на это нельзя полагаться. Кстати, именно так происходит другая перегрузка.

Ответ №2:

Вам нужен ctype.h, чтобы получить правильное определение toupper() . Обычно он реализуется не как функция, а как отображение массива.

  #include <ctype.h>
  

У программы есть несколько недостатков: использование строкового массива вместо строки, неправильная итерация по строке, не объявление, а использование определения toupper() на C, не выход, когда файл не существует.

Используйте это вместо:

 #include <ctype.h>
#include <iostream>
#include <string>
using namespace std;

int main ()
{
  ifstream fin ("data_names.txt");
  if (!fin) 
  {
    cerr << "File missing" << endl;
    return 1;
  }
  // not sure if you were trying to process 5 lines or five words per line
  // but this will process the entire file
  while (!fin.eof())
  {
       string s;
       fin >> s;
       for (i = 0;  i < s.length();    i)
            s [i] = toupper (s [i]);
       cout << s << endl;
  }
  return 0;
}
  

Комментарии:

1. Я полагаю, что в наши дни это обычно реализуется как функция, потому что многие люди называют это передачей простого char в качестве аргумента (что прерывается при реализации массива)

2. Кстати, заголовок C будет cctype , затем используйте std::toupper .

3. @juanchopanza не будет ли код OP по-прежнему выдавать ошибки, если не использовать перегрузку C с 2 параметрами, поскольку он передает a string , когда int ожидается an?

4. @JonnyHenly Да, так и будет. Это будет другая ошибка.

5. @JOHNSMITH8338 Неясно, что вы на самом деле пытаетесь сделать, но lastname[0] это std::string . Чтобы получить его первый символ, который вам понадобится lastname[0][0] . Понятия не имею, почему вы используете массив строк.