Search code examples
c++getline

getline error in C++ code to swap uppercase to lowercase and vice-versa of a user inputted string


I am learning C++ and I came across this error that I cannot seem to fix.

The code should get a string from the user, then swap the uppercase characters to lowercase characters, and lowercase characters to uppercase characters:

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

void swapCase (const string& s)
{
    string str;
    str.assign(s);
    for(int i=0;str[i]!='\0';i++)
    {
        if (str[i] >= 'A' && str[i] <= 'Z')    //checking for uppercase characters
        {
            str[i] = tolower(str[i]);
        }         //converting uppercase to lowercase
        else if (str[i] >= 'a' && str[i] <= 'z')   //checking for lowercase characters
        {
            str[i] = toupper(str[i]);        //converting lowercase to uppercase  
        }
    }
    cout << str << endl; // output
}

int main()
{
    const string str;
    cout << "Enter the string "; //prompt user
    getline(cin, str); // input
    swapCase(str); //send string to function
    return 0;
}
main.cpp:23:3: error: no matching function for call to 'getline'
  getline(cin, &str);

Solution

  • Let me summarize comments: how would I assign a variable to str if I want to keep it as const? answer is: U can't assign nothing to const variables, u can only initialize const variables. In your case u can do the following (showing only posibility not recommend do that):

        string temporary_str;
        getline(cin, temporary_str); // input
        const string str = temporary_str; // not assigning but initializing
        // cant do after initialization: str = tremporary_str; // it is assignation cant be done with const on left side
        swapCase(str); //send string to function
    

    this yours question made me think that u think that u cant pass non-const variables into swapCase. It's wrong: u can pass any string to swapCase. const modifier in function argument means that u wont change this variable inside function. So u can do simply:

        string str;
        cout << "Enter the string "; //prompt user
        getline(cin, str); // input
        swapCase(str); //send string to function
    

    Some other recomendations (in code comments): use std::isupper and std::islower like this:

    #include <iostream>
    #include <string> 
    using namespace std;
    
    void swapCase (const string& s)
    {
        string str = s; // can be done without assign
        for(int i=0; i < str.size(); i++) // not sure that str[i]!='\0' is good idea for c++
        {
            if (isupper(str[i]))    //checking for uppercase characters
            {
                str[i] = tolower(str[i]); //converting uppercase to lowercase
            }
            else if (islower(str[i]))   //checking for lowercase characters
            {
                str[i] = toupper(str[i]);        //converting lowercase to uppercase  
            }
        }
        cout << str << endl; // output
    }
    
    int main()
    {
        string str;
        cout << "Enter the string "; //prompt user
        cout << std::flush; // I recommend it to be exactly displayed on the screen
        getline(cin, str); // input
        swapCase(str); //send string to function
        return 0;
    }
    

    EDIT: some information about flushing: when u write cout << something; it not actually writes it immediately, it says save it to write and at one day it writes out (if program ends with 0 code it writes what it promise), actually flushing is happening time to time automatically but to force write what in internal buffer use std::flash or std::endl because it contains std::flush inside it, the other side of flushing it can slower the program, so if u know that u will write something and u don't actually need to be printed instantly don't use std::endl use \n because it causes flaush only in console but not in file (it was a rough approximation), see code below :

    #include <iostream>
    #include <fstream>
    
    int main() {
        std::cout << "This will be printed because endl have flush inside it" << std::endl;
        std::cout << "This will be printed because flush after it" << std::flush;
        std::cout << "This will be printed in console because in console \\n means flush  \n";
        std::ofstream example_file("example.txt");
        example_file << "This will be printed in file because endl have flush inside it" << std::endl;
        example_file << "This won't be printed in file even with \\n because writing in file \\n doesn't mean flash \n";
        std::cout << "This won't be printed";
        _Exit(1); // imitates something bad happend
    }