1

This is one of the problems I get after first lesson on programming basics lecture

gets() works kinda properly(I think), but "cin" refuses to work

int main(void)
{
    char *s1, *s2;
    puts("Enter your name and surname for gets()");
    gets(s1);
    puts("Enter your name and surname for cin()");
    cin >> s2;
    cout << s1 << "! Hello from gets" << endl;
    cout << s2 << "! Hello from cin" << endl;
    return 0;
}

I expect cin to output what you had typed in console, but after typing programm waits for a second and then everything closes without any output at all.

Screenshot is what our teacher gave us and it's not working

Screenshot

3 Answers3

5

Your program has undefined behavior.

gets expects an argument that points to enough valid memory to read and store the input. In your posted code, s1 does not meet that requirement. Similar problem exists with your usage of cin and s2.

More importantly, don't use gets any more. It's a deprecated function due to security issues. Use std::string and std::getline.

int main(void)
{
   std::string s1;
   std::string s2;

   puts("Enter your name and surname");
   std::getline(std::cin, s1);

   puts("Enter your name and surname again");
   std::getline(std::cin, s2);

   // Use s1 and s2.
   return 0;
}

Useful read: Which functions from the standard library must (should) be avoided?

R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

These pointers

char *s1, *s2;

with the automatic storage duration are not initialized and have indeterminate values. As a result the program has undefined behavior.

Use instead character arrays or objects of the type std::string.

Take into account that the function gets is not supported by the C Standard. Use fgets instead of gets.

Or as this is a C++ program then use std::getline or the member function std::cin.getline.

Pay attention to that this statement

cin >> s2;

does not allow to enter several words separated by white-spaces.

Here is a demonstrative program.

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>

int main() 
{
    const size_t N = 100;
    char s1[N];
    std::string s2;

    std::ios_base::sync_with_stdio();

    std::printf( "Enter your name and surname for fgets(): " );
    std::fgets( s1, sizeof( s1 ), stdin );
    s1[std::strcspn( s1, "\n" )] = '\0';

    std::printf( "Enter your name and surname for std::cin: " );
    std::getline( std::cin, s2 );

    std::cout << s1 << "! Hello from fgets" << std::endl;
    std::cout << s2 << "! Hello from std::cin" << std::endl;

    return 0;
}

Its output might look like

Enter your name and surname for fgets(): Bob Fisher
Enter your name and surname for std::cin: Tomas Man
Bob Fisher! Hello from fgets
Tomas Man! Hello from std::cin
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Спасибо конечно, скину однокурсникам, пускай посмотрят, но мы на первом курсе и это было наше первое занятие по программированию, и я не понял 50% того, что ты написал. Код, приложенный мною в скриншоте взят из методички, написанной преподавателем, и, получается, он не рабочий? –  Sep 04 '19 at 17:09
  • @freshman The code from the training manual is incorrect. As I already wrote, the gets function is not a standard function. Secondly, the sentence cin >> s2; doesn’t allow you to read several words in one line, as it reads up to the first space character. Keep in mind that there is a Russian-language website ru.stackoverflow.com. – Vlad from Moscow Sep 04 '19 at 17:12
  • While valid as an example, just make sure to not mix stdio and iostream in real programs, and prefer to use the iostream library, since reading into a `std::string` is just much safer. – G. Sliepen Sep 04 '19 at 17:12
  • @freshman I think that the most difficult part of the program is this statement s1[std::strcspn( s1, "\n" )] = '\0';. The problem is that the function fgets can append the new line character to the read string. This statement allows to exclude this character from the string. the function strcspn finds the position of the new line character and then it is substituted for the terminating zero character '\0'; – Vlad from Moscow Sep 04 '19 at 17:20
0

Additionally, remember that declaring/creating a pointer variable does not automatically create a pointed-to object. You must always do that explicitly.

char* s = new char[ N ];

...for whatever value N is. Do t forget to free the memory at some point after you have fi wished using it.

delete [] s;

That said, since you are using C++, you can usually avoid handling pointers directly, and if you must, use a std::unique_ptr or a std::shared_ptr

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39