Trying to decide which programming language I want to learn

  • Thread starter yungman
  • Start date
  • #276
4,515
80
I am so stoked reading the GADDIS book, it is so simple. I read the std::string, but I decided to stop and go through what I learn in the last 2 weeks or so. Now I think I have a better feel of the names...........

That object is just a self contained module with both data and programs, it just carry out request from the main program with given parameter and return results. It is like a module that the main program call upon to perform a task.

That cout and cin are object that the main program can call to write a stream onto the console or read as stream from the keyboard, that << and >> are streaming operator.

That header files contain a set of object files of particular type of function that the program to call on. Just like cout and cin are object in iostream for streaming. That we #include <iostream> in order to access to cout and cin.

These were all a blur to me before, the first book doesn't explain any of these. When you guys explain, it's really over my head. This book really starting from basic on up. I went through quite a few pages, I think it's worth my while to even have to stop for a few days and catch up with all the holes I missed.

Before, all the names and terms is just like people's names, why you call John? Why your last name is Jones? It's like I just blindly remember the names and it's hard.

I learn a lot on strings also, but I don't even want to talk about it until I back track all the stuffs and revisit again.

I am stoked.
 
  • #277
4,515
80
I am working of cin.get(). I think I got what I want from the program, BUT, it's really not what I want.

I want the program to read in any character from the keyboard, display it and show the ASCII number. Then loop back to ask another character. I want it to exit when I hit ENTER ( ASCII = 10)

I understand for cin, I need to hit the character and then ENTER to get it going or else it will just sit there and wait. cin.get can recognize ENTER as character. BUT, I still have to hit ENTER again before it will exit the loop. this is because I have to put in cin.ignore to prevent the program from reading the ENTER that is in the stream and exit without looping. Is there any way to exit right when I hit ENTER if I choose to exit?

C++:
#include <iostream>
using namespace std;

int main()
{
    int Ascii = 0;
    char userSelection = 'A';
    do
    {
    cout << "hit any key:  ";
    cin.get(userSelection);
    cin.ignore();
    Ascii = userSelection;
    cout << "you hit: " << userSelection << ",   the ASCII is =  " << Ascii << endl;
    } while (userSelection != 10) ;
    return 0;

}
thanks
 
  • #278
pbuk
Science Advisor
Gold Member
1,535
474
Rather than try and fit an answer into what you wrote, I'm going to totally rewrite it for you. In doing this you will see that nearly every line is different. Apart from the difference between this
C:
int main()
{
  // Code here.
and this
C:
int main() {
  // Code here.
, and 2 spaces of indent vs. 4, which are just different style choices, all the other differences are important. Some of them (like
C:
  int ascii = 0;
vs
C:
    int Ascii = 0;
wont stop your code working, but they can make it more vulnerable to mistakes and you should get into the right habits now.

So here we go, you can also see this working at https://repl.it/repls/RealSubduedAtom. This code is missing comments of course, you might like to add them as you work through it.
C:
#include <iostream>
using namespace std;

#define EOL '\n'

int main() {
  int ascii = 0;
  char userSelection = 0;

  while (userSelection != EOL) {
    cout << "type a key and [enter]: ";
    cin.get(userSelection);
    ascii = userSelection;

    if (userSelection == EOL) continue;

    cin.ignore(255, EOL);
    cout << "the first key was: " << userSelection
      << ", the ASCII is " << ascii << endl;
  }
  return 0;
}
 
  • Like
Likes yungman
  • #279
4,515
80
Thanks, that's what I want, but I don't understand.

So ENTER = '\n' ? I did not know about this!!!

I don't remember whether I can use const char EOL = '\n' instead of #define EOL '\n'

What is continue? I don't see in while loop have anything to do with this.
 
  • #280
jtbell
Mentor
15,584
3,561
What is continue? I don't see in while loop have anything to do with this.
There are two ways to interrupt a cycle of a loop in the middle:
  • break; exits the loop immediately. The next statement executed is the first statement after the loop's closing-brace.
  • continue; jumps back to the beginning of the loop. In a while loop, the loop condition is tested again, then the loop continues or exits accordingly.
Are you sure it's not in your (Gaddis's) book? Have you tried the index at the end of the book? (I don't have it, so I can't check it for myself.)
 
  • Like
Likes yungman
  • #281
jtbell
Mentor
15,584
3,561
if (userSelection == EOL) continue;
Wouldn't break instead of continue also exit the loop cleanly in your example?
 
  • Like
Likes pbuk and yungman
  • #282
jtbell
Mentor
15,584
3,561
You put the user's input in two variables, a char and an int, so you could display it in both formats. Instead, you can use just the char variable to get both formats:
Code:
cout << "the first key was: " << userSelection
      << ", the ASCII is " << int(userSelection) << endl;
We call this "casting" the char variable to int.

It works the other way, too. If you have int ascii = 97;, then cout << char(ascii) displays a.
 
  • Like
Likes pbuk
  • #283
4,515
80
So here we go, you can also see this working at https://repl.it/repls/RealSubduedAtom. This code is missing comments of course, you might like to add them as you work through it.
C:
#include <iostream>
using namespace std;

#define EOL '\n'

int main() {
  int ascii = 0;
  char userSelection = 0;

  while (userSelection != EOL) {
    cout << "type a key and [enter]: ";
    cin.get(userSelection);
    ascii = userSelection;

    if (userSelection == EOL) continue;

    cin.ignore(255, EOL);
    cout << "the first key was: " << userSelection
      << ", the ASCII is " << ascii << endl;
  }
  return 0;
}
Thanks for the program. I think I understand, I just want to confirm one thing.

When cin.get(userSelection), it read two characters into the keyboard buffer: first character and the '\n' as last character. The userSelection contain the first character after the cin.get() line.
Then in the line if (userSelection == EOL), This read out the next character from the keyboard buffer, which is '\n'.

Just want to confirm this.

Thanks
 
  • #284
pbuk
Science Advisor
Gold Member
1,535
474
Thanks for the program. I think I understand, I just want to confirm one thing.

When cin.get(userSelection), it read two characters into the keyboard buffer: first character and the '\n' as last character. The userSelection contain the first character after the cin.get() line.
No, that's not quite right. First of all the code you write does not read into a buffer, this part is done by the operating system. Also, cin is actually a line input buffer cin.get which is why you have to hit enter, rather than a keyboard buffer which reads keys straight away.

So cin.get(userSelection) waits for a character to appear in the keyboard line input buffer (which will only happen after return has been entered) and then reads one character from the buffer into userSelection which is passed by reference.

Then in the line if (userSelection == EOL), This read out the next character from the keyboard buffer, which is '\n'.
Does it look like this code reads anything from any input buffer?
 
  • #285
pbuk
Science Advisor
Gold Member
1,535
474
Wouldn't break instead of continue also exit the loop cleanly in your example?
Yes it would, but breaking out of a while(true) loop is not a very understandable way to write code. Putting the termination condition up front makes it much easier to see when you want the loop to terminate.

You put the user's input in two variables, a char and an int, so you could display it in both formats. Instead, you can use just the char variable to get both formats:
Code:
cout << "the first key was: " << userSelection
      << ", the ASCII is " << int(userSelection) << endl;
We call this "casting" the char variable to int.

It works the other way, too. If you have int ascii = 97;, then cout << char(ascii) displays a.
Yes this is the way I would normally do it but the OP used two variables so I kept to that. Note that you can also cast using (int) userSelection which the compiler treats exactly the same way; I prefer this because int(userSelection) looks like a function call. Note also that when you do ascii = userSelection the compiler is performing an implicit cast. With certain compiler settings, userSelection = ascii will report a warning, @yungman can you think why?
 
  • #286
4,515
80
I think I got it.

Thanks
 
  • #287
jtbell
Mentor
15,584
3,561
So cin.get(userSelection) waits for a character to appear in the keyboard line input buffer (which will only happen after return has been entered) and then reads one character from the buffer into userSelection which is passed by reference.
And of course your cin.ignore() ensures that, if you enter more than one character before pressing 'return', the program processes only the first one and skips over the rest.

A useful exercise for yungman: "comment out" the cin.ignore(), recompile, run, and then enter a word instead of a single character and see what happens.
 
  • Like
Likes yungman
  • #288
4,515
80
I want to know how the keyboard buffer works when using cin, cin.get and cin.ignore.

I still want to confirm about how cin.get can make it jump out of the loop with just hitting ENTER where the rest of the character, you need to enter the character, then press ENTER. Please check what I said is correct or not.

My understanding is when cin >>character, it needs to hit ENTER before it does anything. When hitting ENTER, two characters are stored in the keyboard buffer........the character and '\n'. cin read the first character, leaving the '\n' in the keyboard buffer. If cin.get() follows, it immediate read the '\n' from the last cin and treat it as a character and move on without reading the character supposed to be entered from the keyboard.

I still don't get how C++ pick which character to read in the keyboard buffer, when is it start reading, is it only read when hitting the ENTER key?
 
  • #289
pbuk
Science Advisor
Gold Member
1,535
474
I want to know how the keyboard buffer works when using cin, cin.get and cin.ignore.

I still want to confirm about how cin.get can make it jump out of the loop with just hitting ENTER where the rest of the character, you need to enter the character, then press ENTER. Please check what I said is correct or not.
I am sorry, I can't really understand what you are saying. If you want to work out how it works the best thing is just to play with it.

My understanding is when cin >>character, it needs to hit ENTER before it does anything.
Correct, you won't see anything from cin until you hit enter.
When hitting ENTER, two characters are stored in the keyboard buffer........the character and '\n'.
As many characters as you have typed before hitting enter are in the buffer - it could be 0, 1 or many - as well as the \n (i.e. ENTER) character.

cin read the first character, leaving the '\n' in the keyboard buffer.
Only if it was there - if the first and only character was \n then the buffer is now empty.

If cin.get() follows, it immediate read the '\n' from the last cin and treat it as a character and move on without reading the character supposed to be entered from the keyboard.
Nowhere in either your code or mine is one cin.get() followed by another.

I still don't get how C++ pick which character to read in the keyboard buffer, when is it start reading, is it only read when hitting the ENTER key?
Not exactly. In order for the buffer to be read, two conditions must be satisfied:
  1. the operating system must have stored characters in the buffer; this only happens when you hit ENTER
  2. your code must try to read from the buffer; this only happens when you reach the (compiled) cin.get() statement.
Once both these conditions are satisfied, cin.get() knows that you are looking for a char type so it reads exactly one byte from the buffer. If you have only typed \n, that is what you will get and the buffer will be empty so if you immediately try to flush it your program will wait around for another character to flush. That's why I checked straight away to see if ENTER was the character received from the buffer.
 
  • #290
pbuk
Science Advisor
Gold Member
1,535
474
Somewhere near the beginning of this thread I think I recommended codecademy. I think the way codecademy leads you through exercises would be useful. Please give it a try.
 
  • Like
Likes FactChecker
  • #291
4,515
80
And of course your cin.ignore() ensures that, if you enter more than one character before pressing 'return', the program processes only the first one and skips over the rest.

A useful exercise for yungman: "comment out" the cin.ignore(), recompile, run, and then enter a word instead of a single character and see what happens.
Yes, I wrote a program with words reading in last name and first, then print out, then as to hit ENTER to quit or any other character to do it again:
C++:
// enter multiple data in one cin
#include <iostream>
using namespace std;

int main()
{
    char LastName[21] = { '\n' }, FirstName[21] = { '\n' };
    char userSelection = 'A';
    do
    {
    cout << endl;
    cout << "Enter LastName and FirstName with a space in between, then hit ENTER "<< "\n";
    cin >> LastName >> FirstName;
    cout << "\n";
    cout << "You entered  " << LastName << " " << FirstName << endl;
    cout << "\n";
    cin.ignore(255, '\n');// clear ENTER
    cout << " Hit any character to repeat, hit ENTER to quit ";
    cout << endl;
    cin.get(userSelection);
    } while (userSelection != '\n');
    return 0;
}
 
  • #292
jtbell
Mentor
15,584
3,561
It seems that in order to do exactly what you want (read a newline character from an input stream, just like any other char), C++ would have to allow for "unbuffered input streams." And C++ simply doesn't provide this capability. All I/O is via abstract streams, which could be connected to your keyboard and display, or to files, or to network sockets...

At least that's how I interpret the following discussion that I found with a Google search for "c++ unbuffered console input":

https://www.daniweb.com/programming...reads/451301/why-no-standard-unbuffered-input

I think I remember reading similar things elsewhere years ago when I was more involved in C++ by teaching it.

There's at least one way to accomplish your ultimate goal, which is to allow the user to terminate an input loop by simply pressing <return>. You don't read to a single char, but to an std::string. And insted of using cin >>, you use the std::getline() function, which reads from an input stream (e.g. cin) until it encounters a newline. The chars up to (but not including) the newline go into the string, and the newline is discarded. To test whether the user simply pressed <return>, you test the string to see if it's empty.

Code:
#include <iostream>
#include <string>

int main ()
{
    std::string choice = "go";
    while (choice != "")
    {
        std::cout << "Enter a character, or <return> to exit: ";
        std::getline (std::cin, choice);
        std::cout << "You entered '" << choice << "'." << std::endl;
        if (choice != "")
        {
            std::cout << "'" << choice[0] << "'" 
              << " has the ASCII code " << int(choice[0]) << "." 
              << std::endl;
        }
    }
    return 0;
}
If the user enters more than one char before pressing <return>, this program displays all of them, but displays the ASCII code for only the first one. Exercise: modify the program so it displays the ASCII codes for all the chars that the user enters.
 
  • #293
pbuk
Science Advisor
Gold Member
1,535
474
It seems that in order to do exactly what you want (read a newline character from an input stream, just like any other char), C++ would have to allow for "unbuffered input streams." And C++ simply doesn't provide this capability. All I/O is via abstract streams, which could be connected to your keyboard and display, or to files, or to network sockets...
No, there is no problem with reading a newline character from an input stream as you can see from my code in #278(!). The problem with @yungman's code was that after reading one character (which could be a newline) he was calling ignore() which was waiting around for another newline.

There's at least one way to accomplish your ultimate goal, which is to allow the user to terminate an input loop by simply pressing <return>. You don't read to a single char, but to an std::string. And insted of using cin >>, you use the std::getline() function, which reads from an input stream (e.g. cin) until it encounters a newline. The chars up to (but not including) the newline go into the string, and the newline is discarded. To test whether the user simply pressed <return>, you test the string to see if it's empty.
Yes, std::getline() is generally more useful than cin >>. But actually neither of these are very useful - interactive console programs aren't really a thing in C++; if I were @yungman I'd drop it and move on.
 
  • #294
4,515
80
I run into problem building the solution. I got an error message
C++:
// Read and write to file
#include<iostream>
#include<fstream>
using namespace std;

int main()
{
    ofstream outputFile;
    outputFile.open("demofile.txt");
    cout << "Now writing data to the demofile.txt" << endl;
    outputFile << "Bach\n";
    outputFile << "Beethoven\n";
    outputFile << "Mozart\n";
    outputFile << "Schubert\n";

    outputFile.close();
    cout << "Done " << endl;
    cout << endl;
    return 0;

}
Compile error file write.jpg


I triple checked, I type everything right straight out from the book. Please help

Thanks
 
Last edited:
  • #295
1,555
837
The error message says that your path name length plus the generated file name length exceeds the 250 character limit. You can reduce the length by reducing the number or lengths of the concatenated components. For example, the generated file name includes your project name, so using a shorter project name would contribute to staying within the limit.

https://stackoverflow.com/questions...-file-the-spcified-path-filename-are-too-long
 
  • Like
Likes yungman
  • #296
4,515
80
The error message says that your path name length plus the generated file name length exceeds the 250 character limit. You can reduce the length by reducing the number or lengths of the concatenated components. For example, the generated file name includes your project name, so using a shorter project name would contribute to staying within the limit.

https://stackoverflow.com/questions...-file-the-spcified-path-filename-are-too-long
I don't understand, it is a new file as you see created by the program named "demofile.txt". It only contain 4 words( 4 names). It is less than 50 characters if you count them all including the name of the file.

thanks

EDIT: I went in and deleted 3 out of 4 names, still fail.
 
Last edited:
  • #297
1,555
837
I don't understand, it is a new file as you see created by the program named "demofile.txt". It only contain 4 words( 4 names). It is less than 50 characters if you count them all including the name of the file.

thanks
Please look at the file name in the error message ##-## it's between quotation marks, and it's about 100 characters long. The file name that the message is reporting is the VS-generated name of a debug file. The fully-qualified name includes the path name, which includes everything in the directory structure from the drive letter to the most deeply nested current subdirectory. It also includes the whole of your project name, which lengthily describes the program, instead of just being something like P002. You can also rename directories to something shorter, e.g. abbreviate Microsoft to MS, and Visual Studio to VS. The full path character string from drive letter to current subdirectory doesn't appear in the message, so I can't see all the reductions you could do to reduce its length.
 
  • Like
Likes yungman
  • #298
jtbell
Mentor
15,584
3,561
Please look at the file name in the error message it's between quotation marks, and it's about 100 characters long.
I think I copied it correctly here:

Debug\3.29 rea.63bf1643e.tlog\3.29 read write to file ifstream ofstream open close.lastbuildstate

The full path name is probably much longer, as sysprog described.

I suspect that "3.29 read write to file ifstream ofstream open close" is the name that yungman chose for the project or something related to it. It looks like an exercise number (3.29) followed by keywords describing the program to help him find it later. "lastbuildstate" looks like it might be a suffix generated by Visual Studio for internal purposes.

I suggest that he go to wherever he entered that name, and replace it with a much shorter one, maybe something like "3.29 fstream".

I'm just guessing here, because I've never used Visual Studio.

I copied and pasted the program as shown, into a .cpp file on my iMac. My compiler (g++) compiles it successfully, and it produces the expected output.
 
  • Like
Likes yungman and sysprog
  • #299
33,722
5,418
Debug\3.29 rea.63bf1643e.tlog\3.29 read write to file ifstream ofstream open close.lastbuildstate

The full path name is probably much longer, as sysprog described.
I'm just guessing here, because I've never used Visual Studio.
I agree with @jtbell and @sysprog that the filename of the source code is the problem.
I copied the program verbatim and ran it through VS, and it worked as expected.
 
  • Like
Likes sysprog
  • #300
4,515
80
I solved the problem. It is the name of my whole project I created!! I tried to make it more descriptive on the name so in the future when I read the name, I can know what the program does. This is old age for you, can't remember after a while. 3.29 doesn't mean anything to me later on. I did a lot of exercise with the first book and I don't remember what they are until I open them. So for the Gaddi's book I give descriptions............AND it's too long!!!

Now, I deleted the whole project, saving only the source.cpp. Create a new project called 3.29 ofstream and it compiled.

VS has strange things, I found the demofile.txt that created by the program now. Also VS is strange, I before I end up deleting the whole project, I tried to change the name of EVERY file inside, it's like every time I navigate around, I see new names that I missed the first time!!! It just did not work trying to rename the files, finally, I had to take out the source.cpp, then try to delete. Then I had to close all the other projects ( I had the ifstream project opened in another VS program) in order to even create the new 3.29 ofstream.

Now my other ifstream doesn't read the demofile.txt. That's another story for another day. I want to work on that first.
 
Last edited:
  • Like
Likes jtbell
Top