getline causing Segmentation fault

Newbie here,
I am using getline in order to take in a sentence with spaces in it. Typing in a sentence with no spaces does not cause a Segmentation fault (core dumped) error. Oddly enough, typing in, "Z L" does not cause the error either, but for example, "Z LL","Z LLLL" "ZZZ LL" all do (random characters).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
using namespace std;
int main() 
{
char a1[20];

cout<<"Please type in a grammatically correct sentence of 3 words using no punctuation ";
cin.getline (a1, 20);
string a = a1;
cout<<endl<< a <<endl;
int q2=a.length();//Cause of Error?
cout<< "test 1"; // the error appears before this
int q1=0;
for(int q=0;q<q2;q++)
{ cout<<"test";
	if(a[q]==' ')
		{cout<<q1;
		q1++;}
}
if(q1<1)
	{cout<<"Ungrammatical, less than 3 words"<<endl;
	return(0);}



This issue appeared as soon as getline was first used. I've been searching for the past day for a solution, and I've unsuccessfully attempted cin.ignore() and the like. I've added the int q2 line in order to try and pinpoint the cause, and I understand that it is redundant and can be skipped and just directly used in the for loop.
The 'best results' I've obtained is with the code I posted- I started off first not using char, but I would always get the error, regardless of what was inputted.
line 22 should be
{cout<<"Ungrammatical, less than 3 words"<<endl;}

After trying to figure out what your doing I came up with this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
using namespace std;
int main() 
{
char a1[20];
cout<<"Please type in a grammatically correct sentence of 3 words using no punctuation ";
cin.getline (a1, 20);
string a = a1;

int q1=0; // counter
for(int q=0;q<a.length();q++)
	{ 
	if(a[q]==' ')
		{q1++;}
	}

if(q1<1)
		{cout<<"Ungrammatical, less than 3 words"<<endl;}
else 
	{cout << "spaces = "<<q1;}
return(0);
}
Last edited on
@SamuelAdams
the code goes beyond what i pasted- but I want it to exit if its ungrammatical, thus the return(0) before the }. Does the return cause this error? Should I remove it fully?
Why are you using the C-string? Why not just use a std::string in the first place with the proper getline() function? There are two getline() functions one that works with the C-string, the one you're using, and one that works with the std::string.

http://www.cplusplus.com/reference/string/string/getline/

By the way I can't duplicate your problem. The program runs without crashing.

You also need to find and consistently use an indentation style you like.

https://en.wikipedia.org/wiki/Indent_style

This along with a little added whitespace will make your code much easier to read.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>

using namespace std;

int main()
{
    char a1[20];

    cout << "Please type in a grammatically correct sentence of 3 words using no punctuation ";
    cin.getline (a1, 20);
    string a = a1;
    cout << endl << a << endl;
    int q2 = a.length();//Cause of Error?
    cout << "test 1"; // the error appears before this
    int q1 = 0;

    for(int q = 0; q < q2; q++)
    {
        cout << "test";
        if(a[q] == ' ')
        {
            cout << q1;
            q1++;
        }
    }

    if(q1 < 1)
    {
        cout << "Ungrammatical, less than 3 words" << endl;
        return(0);
    }
}
Probably is just an isolated incident as I can't reproduce it either.
In the code you posted you had 4 { but only 3 } which will not work.

Other than that I didn't see any problems with the code.

I changed the for statement only because I didn't think you needed q2, but it worked fine using q2 before I changed it.
Last edited on
@jlb thank you for your quick reply-
Its odd that it works for you but stops at a certain point where I'd assume I would find the source of the error. I just went back and removed bits and bits of code until i could run the program without crashing and found this to be the final bit where I would still crash. Is this situation (where code crashes at a certain point due to code that wasn't even "visibly" reached?) common? Regardless,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <string>

using namespace std;

int main()
{
    char a1[20];

    cout << "Please type in a grammatically correct sentence of 3 words using no punctuation ";
    cin.getline (a1, 20);
    string a = a1;
    cout << endl << a << endl;
    int q2 = a.length();//Cause of Error?
    cout << "test 1"; // the error appears before this
    int q1 = 0;

    for(int q = 0; q < q2; q++)
    {
        cout << "test";
        if(a[q] == ' ')
        {
            cout << q1;
            q1++;
        }
    }

    if(q1 < 1)
    {
        cout << "Ungrammatical, less than 3 words" << endl;
        return(0);
    }
string word1= " "; //the words the user enters are attempted to be split
string word2= " ";
string word3= " ";
bool one= true;
bool two= false;
bool three= false;
for(int i=0;i<a.length();i++)
{
	if (a[i] !=' 'and one==true)
	{string word1 = word1 + a[i];}

	if (a[i] == ' 'and one==true)
	{bool one=false;
	 bool two=true;}

	if (a[i] != ' 'and  two==true)
	{string word2 = word2 + a[i];}

	if (a[i] == ' ' and two==true)
	{bool two=false;
	 bool three=true;}

	if (a[i] != ' 'and three==true)
	{string word3 = word3 + a[i];}

	if (a[i] == ' 'and  one==true)
	{bool three=false;}
}

cout<<word1<<" "<<word2<<" "<< word3<<endl;

	}

I understand this code might have many more mistakes in it- I would appreciate only receiving feedback on the error i started this topic for if possible. If it is all tied in, sure, but I would prefer learning from my own mistakes and not have this code being fully written out!
Again, thank you for your replies and help
If you comment out lines 41&42, 48&49, 55&56 you program will not crash.

try changing the lines from
{string word1 = word1 + a[i];}
to
{word1 = word1 + a[i];}
Notwithstanding the blooper in not taking the advice of jlb, an experienced programmer, "and" is not legal in C++. && is! But only fix it up if you want to. :)
@SamuelAdams,
wow, it works!
Thank you so much your help, and everyone else's.
Could you also explain, if you know, why this would lead to an error as this?
Cheers!

@kemort,
I didn't mean any offense in not changing my style and taking other advice, as I was focused on fixing this error that's been driving me nuts for the past day. I'll get on fixing everything else next!
Last edited on
> "and" is not legal in C++

and is a keyword. http://en.cppreference.com/w/cpp/keyword/and

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <string>
#include <cctype>
#include <sstream>

int main()
{
    std::cout << "type in a sentence of 3 words using no punctuation\n";
    std::string str ;
    std::getline( std::cin, str );

    for( char c : str ) if( std::ispunct(c) )
    {
        std::cerr << "punctuation\n" ;
        return 1 ;
    }
    
    // count the number of words
    std::istringstream stm(str) ;
    std::string word ;
    int word_count = 0 ;
    while( stm >> word ) ++word_count ;

    if( word_count < 3 )
    {
        std::cerr << "less than three words\n" ;
        return 1 ;
    }

    if( word_count > 3 )
    {
        std::cerr << "more than three words\n" ;
        return 1 ;
    }

    // ...
}

Last edited on
You declared string word1, 2, 3.
1
2
3
string word1= " "; //the words the user enters are attempted to be split
string word2= " ";
string word3= " ";


Then you tried to do it again if you hit this condition.

1
2
if (a[i] !=' 'and one==true)
	{string word1 = word1 + a[i];}


The computer has a way of saying NO when you do something your not supposed to do :P

In short I think it's saying no I have that mapped to memory already, I'm not going to do it again, have a nice day BYE.


Thank you everyone for your help,
I'll check out the rest of the advice you've all given me and I'll be sure to check up on my 'and' usage.
Cheers!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <string>
#include <cctype>
#include <sstream>

int main()
{
    std::cout << "type in a sentence of 3 words using no punctuation\n";
    std::string str ;
    std::getline( std::cin, str );

    for( char c : str ) if( std::ispunct(c) )
    {
        std::cerr << "found punctuation\n" ;
        return 1 ;
    }

    std::istringstream stm(str) ;
    std::string word1, word2, word3, word4 ;
    if( stm >> word1 >> word2 >> word3 && !( stm >> word4 ) )
    {
        std::cout << "well done. the three words are:\n"
                  << word1 << '\n' << word2 << '\n' << word3 << '\n' ;
    }
    else
    {
        std::cerr << "number of words is not equal to three\n" ;
        return 1 ;
    }
}
We all live and learn ... but

That link you provided appears to be a PHP link not C++.

From the C++ standard:


2.6 Alternative tokens [lex.digraph]
1. Alternative token representations are provided for some operators and punctuators. (16)
2. In all respects of the language, each alternative token behaves the same, respectively, as its primary token, except for its spelling.(17) The set of alternative tokens is defined in Table 2.


(16) These include “digraphs” and additional reserved words. The term “digraph” (token consisting of two characters) is not perfectly descriptive, since one of the alternative preprocessing-tokens is %:%: and of course several primary tokens contain two characters. Nonetheless, those alternative tokens that aren’t lexical keywords are colloquially known as “digraphs”.
(17) Thus the “stringized” values (16.3.2) of [ and <: will be different, maintaining the source spelling, but the tokens can otherwise be freely interchanged.

True
Topic archived. No new replies allowed.