0

I am working on my assignment and I have come across an error that i would like to understand (assuming this is an error and not just me overthinking the question). My current output is giving me one word at a time whereas i would like to display a line at a time. Here is my code:

/*
///////////////////////////////////////////////////////////////////////////
Write a program that creates an array of 100 string objects. Fill the
array by having your program open a (text) file and read one line of the
file into each string until you have filled the array. Display the array
using the format “line #: <string>,” where # is the actual line number
(you can use the array counter for this value) and <string> is the stored
string.
///////////////////////////////////////////////////////////////////////////
*/

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int main ()
{
    string story[100];  // create array of 100 string objects
    string filename = "testfile.txt";
    ifstream file(filename); //open file

    // go through array till index 100
    for( int x=0; x<= 100; x++)
    {
       file >> story[x]; // get line and store into array
       cout << "Line " << x << ":" << story[x] << endl; // display
    }

    return 0;
}

And here is the output:

I 
ordered
this
sandwich
once
with
paper .....

whereas i want this:

I ordered this sandwich once with paper-thin carrots in it.
I can’t remember what else. 
I tried to recreate it.
Mr_Pouet
  • 4,061
  • 8
  • 36
  • 47

2 Answers2

3

A quick fix is to replace file >> story[x]; by

std::getline(file, story[x]);

as file >> story[x] reads word by word, whereas std::getline reads the whole line.

However, I'd change string story[100]; to a std::vector<std::string> story; instead, since you don't know in advance how many lines your file has, and you may go out of bounds. With a vector, there is no such issue, you can keep push_back into it inside a loop:

std::string line;
while(std::getline(file, line))
{
    story.push_back(line);
}
vsoftco
  • 55,410
  • 12
  • 139
  • 252
  • I had originally thought of using vectors first but i wanted to practice using an array this time around. Thank you for the suggestion ! Now with the context of my assignment question, would you say the original output of one word per line would be more acceptable or would the new output? – KingShahmoo Dec 22 '15 at 02:19
  • 1
    @KingShahmoo The assignment clearly states that you need to read line by line though, so you definitely must use `std::getline`. However such hw are asking for trouble, as overflowing array bounds is one of the worst nightmare in C or C++ code. At least you make sure you don't read more than 100 lines in the `for` loop, which is OK (but replace `<=` with `<`, as otherwise you read 101 lines into a 100 element array and all bets are off). – vsoftco Dec 22 '15 at 02:20
1

The default delimiter for operator>> is any whitespace. So file >> story[x]; reads a whitespace-delimited set of characters.

You can fix this on the input side either by changing the default delimiter (overly complex, but look at this question) or by using std::getline(file, story[x]);

Alternatively, if you want to store your array of words, you can change the code on the output side. Loop over lines, add a check so that if a word ends in '.' the line ends. Output a space after each word and std::endl at the end of the line.

Community
  • 1
  • 1
KarlM
  • 1,614
  • 18
  • 28