how to use getline() properly and how to use strcpy with a string a const char*

I get an error when I try to use cin.getline(line). Also, I can get strcpy(line, tempString) to work. It says no conversion exists between sting and const char*. Not sure why I get this when both are declared as string.

Any help is appreciated. thanks for your time.

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
  // Purpose:   prompts the user for a 5 line limerick and writes the data to the root directory in binary format
// Date:       9/8/2014
// Filename:   SaveLimerick.cpp
// Input:       5 line limerick poem
// Output:     5 line limerick in binary format

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

int main()
{
	string line;
	const char QUIT = 'Q';
	const char* FILENAME = "C:\\Limerick.dat";
	ofstream writingFile(FILENAME);

	if (!writingFile.good())
		cout << "File could not be opened for writing" <<
		endl;
	else
	{
		cout << "Enter a line or Q to quit: ";
		cin.getline(line);
		while (line[0] != QUIT)
		{
			string tempString = " ";
			writingFile.write(reinterpret_cast <const char*>(&line), sizeof(line));
			cout << "Enter a line or Q to quit ";
			cin.getline (tempString);
			strcpy(line, tempString);
		}

	}

	//closes file
	writingFile.close();

	system("Pause");
	return 0;
}
Last edited on
There are two differing syntaxes for getline, depending on whether you use a char array, or std::string.
change
 
    cin.getline(line);
to
 
    getline(cin, line);



strcpy() is not needed when assigning to a std::string. Change this
 
    strcpy(line, tempString);
to this
 
    line = tempString;


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

http://www.cplusplus.com/reference/string/string/operator=/

Also this line looks both overly complex, as well as incorrect:
 
    writingFile.write(reinterpret_cast <const char*>(&line), sizeof(line));


you could perhaps put
 
    writingFile.write(line.c_str(), line.size());
but it would be simpler to put
 
    writingFile << line;
Last edited on
Hey, Thanks. That getline(cin, line); seemed to work. I revised my code as shown. I changed it a bit because I am required to store it in binary output.

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
// Purpose:   prompts the user for a 5 line limerick and writes the data to the root directory in binary format
// Date:       9/8/2014
// Filename:   SaveLimerick.cpp
// Input:       5 line limerick poem
// Output:     5 line limerick in binary format

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

int main()
{
	string line;
	int lineNum = 1;

	const char* FILENAME = "C:\\Users\\Admin\\Limerick.dat";
	ofstream writingFile(FILENAME, ios::out | ios::binary);



	if (!writingFile.good())
		cout << "File could not be opened for writing" <<
		endl;
	else
	{
		cout << "You will be prompted for 5 lines of a Limerick poem." << endl << endl;

		while (lineNum != 6)
		{
			string tempString;
			cout << "Enter line " << lineNum << ": ";
			getline(cin, tempString);
			writingFile.write(reinterpret_cast <const char*>(&tempString), sizeof(tempString));
			++lineNum;
		}

	}

	//closes file
	writingFile.close();

	system("Pause");
	return 0;
}




however when I try to retrieve the Limerickdat file using a seperate program i get gibberish for some of the lines. I'm not sure where the problem lies. Any ideas.


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
// Purpose:   retrieves a limerick from file Limerick.dat and displays it
// Date:       9/8/2014
// Filename:   DisplayLimerick.cpp
// Input:       5 line limerick poem from Limerick.dat file
// Output:     displays the limerick

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

int main()
{
	string line;
	int lineNum = 1;
	const char* FILENAME = "C:\\Users\\Admin\\Limerick.dat";
	ifstream readingFile(FILENAME, ios::in | ios::binary);

	if (!readingFile.good())
		cout << "File could not be opened for reading" <<
		endl;
	else
	{
		while (lineNum != 6)
		{

			readingFile.read(reinterpret_cast <char*>(&line), sizeof(line));
			cout << lineNum << ":  " << line << endl;
			++lineNum;
		}

	}

	//closes file
	readingFile.close();

	system("Pause");
	return 0;
}


Thanks for looking.
Think about this:
1
2
3
4
5
6
7
8
9
10
#include<iostream>
#include<string>

int main() {
  std::string line1 = "A";
  std::string line2 = "File could not be opened for reading";
  std::cout << sizeof(line1) << '\n';
  std::cout << sizeof(line2) << '\n';
  return 0;
}
hmm...so a string is the same size no matter how many characters it holds. I got 28 for both, line1 and line 2. I'm not sure how to apply this. I think you are telling me to change this somehow: writingFile.write(reinterpret_cast <const char*>(&tempString), sizeof(tempString)); I'm not sure. Can I get another hint?
The thing is that string allocates dynamically space for the text that it holds. In other words, the text is not within those 28 bytes (my environment has 8 byte strings).

A websearch tells that you don't simply write a string as binary. You must write the size and then the data. Likewise, you must read the size and then the data. For example:
http://baptiste-wicht.com/posts/2011/06/write-and-read-binary-files-in-c.html

This is usually called serialization. http://en.wikipedia.org/wiki/Serialization
Boost probably has a library for serialization too.
Hey, thanks for the feedback. I revised my code to use a char array of size 100. I still get gibberish however. Not sure why. both programs compile but I get a blocks of lines when I try to retrieve the limerick. Any ideas?

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
// Purpose:   prompts the user for a 5 line limerick 
// Date:       9/8/2014
// Filename:   SaveLimerick.cpp
// Input:       5 line limerick poem
// Output:     5 line limerick in binary format

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

template<typename T>
ostream& binary_write(std ostream& stream, const T& value)
{
	return stream.write(reinterpret_cast<const char*>(&value), sizeof(T));
}

int main()
{
	char tempChar[100];
	const char* FILENAME = "C:\\Users\\Admin\\Limerick.dat";
	ofstream writingFile(FILENAME, ios::out | ios::binary);
	
	//creates fixed length dat file
	for (int x = 0; x < 6; ++x)
		binary_write(cout, tempChar)


	if (!writingFile.good())
		cout << "File could not be opened for writing" <<
		endl;
	else
	{
		cout << "You will be prompted for 5 lines of a Limerick poem." << endl << endl;

		for (int x = 0; x < 6; ++x)
		{
			
			cout << "Enter line " << x << ": ";
			cin.getline(tempChar);
			writingFile.seekp((x - 1) * sizeof(tempChar));
			binary_write(stream, tempChar);
			
		}

	}

	//closes file
	writingFile.close();

	system("Pause");
	return 0;
}


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
// Purpose:   retrieves a limerick from file Limerick.dat and displays it
// Date:       9/8/2014
// Filename:   DisplayLimerick.cpp
// Input:       5 line limerick poem from Limerick.dat file
// Output:     displays the limerick

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


int main()
{
	
	const char* FILENAME = "C:\\Users\\Admin\\Limerick.dat";
	ifstream readingFile(FILENAME, ios::in | ios::binary);
	

	if (!readingFile.good())
		cout << "File could not be opened for reading" <<
		endl;
	else
	{
		for (int x = 0; x < 6; ++x)
		{
			char tempChar[100];
			readingFile.seekg((x - 1) * sizeof(tempChar));
			readingFile.read(reinterpret_cast <char*>(&tempChar), sizeof(tempChar));
			cout << x << ":  " << tempChar << endl;
			
		}

	}

	//closes file
	readingFile.close();

	system("Pause");
	return 0;
}
There are several compilation errors in the above code.
Line 14
 
    ostream& binary_write(std ostream& stream, const T& value)
should be
 
    ostream& binary_write(std::ostream& stream, const T& value)


Line 27 - missing semicolon
 
    binary_write(cout, tempChar)


Line 41
 
    cin.getline(tempChar);
should be
 
    cin.getline(tempChar, sizeof(tempChar));


Line 43
 
    binary_write(stream, tempChar);
should be
 
    binary_write(writingFile, tempChar);


If you still require help, please post the latest version of the actual code which you are running, otherwise there's no way to tell where the problems are.
Topic archived. No new replies allowed.