First letters being erased when reading from data file c++ - c++

Can someone please explain why only the first letters are being deleted when reading in from a data file but only on the 1/2/3 parts of the array and not the 0 part? (sorry really don't know how to explain it)(I'll only include part of what I am getting as well as data file)
What i get
GoogleyleSmith01#gmail.comyleman27ecurity question:White rabbit with a watch
Deviantartragonmaster27andalfthegreyNULL
What it's supposed to be
GoogleKyleSmith01#gmail.comKyleman27securityquestion:Whiterabbitwithawatch
DeviantartDragonmaster27GandalfthegreyNULL
And the original data file
Google;KyleSmith01#gmail.com;Kyleman27;security question:White rabbit with a watch;
Deviantart;Dragonmaster27;Gandalfthegrey; NULL;
I won't include all of the code as it shouldn't be relevant to this issue
#include<iostream>
#include <fstream>
#include <string>
#include <vector>
#include<sstream>
using namespace std;
const int NCOLS = 4;
const int NROWS = 10;
void description_and_options(string data[][NCOLS], int count[NCOLS]);
void available_options();
void view_line_data(int choice,string data[][NCOLS]);
int main()
{
ifstream file_name;//create the new file
string user_input_file;//the files name inputed by the user
int stringlength;
string read_in_array[NROWS][NCOLS];
string line;
int counter[10] = { 1,2,3,4,5,6,7,8,9,10 };
string user_option_choice;
string small_exit = "x";
string large_exit = "X";
int view_choice;
cout << "Enter the name of the input file: ";
cin >> user_input_file;
if (user_input_file.length() > 4)// check to see if its more than 4 in length
{
stringlength = user_input_file.length(); //saves length
if (user_input_file.substr(stringlength - 4, 4) == ".txt")//checks to see if its .dat
{
file_name.open(user_input_file.c_str());
if (file_name.fail())
{
cerr << "The file " << user_input_file << " failed to open.\n";//tells user if it fails
exit(1);
}
}
}
else
{
user_input_file += ".txt";//adds .dat to non .dat
file_name.open(user_input_file.c_str());
}
if (file_name.fail())
{
cout << "File failed to open" << endl;
system("PAUSE");
exit(1);
}
for (int row = 0; row <= 9; row++)
{
for (int col = 0; col < 4; col++)
{
if (getline(file_name, line, ';'))
{
file_name.ignore(1, '\n');
read_in_array[row][col] = line;
cout << read_in_array[row][col];
}
}
cout << endl;
}
//[updown][leftright]
file_name.close();
is there anyway to fix this without completely changing the code?

It is ignoring the first character because you tell it to
file_name.ignore(1, '\n');
Is going to ignore the first character in the stream after each call to getline. It looks like you are doing this because you think the ; in the file it still there. What you need to remember about getline is that it discards the delimiter you use. That means it will read until it finds a ; and then it tosses that ; out. This means you do not need to ignore it since it is no longer there.
Just removing the call to ignore is not enough to fix the issue though. Since you are trying to parse an entire line what we need to do is read the line into a stringstream and then call getline on the stream to get the individual parts. This is because just reading to ; is going to capture the newline.
A quick refactor of your code gives you something that should look like
for (int row = 0; row <= 9; row++)
{
std::string temp;
std::getline(file_name, temp)
std::stringstream ss(temp)
for (int col = 0; col < 4; col++)
{
if (getline(ss, line, ';'))
{
read_in_array[row][col] = line;
cout << read_in_array[row][col];
}
}
cout << endl;
}

You are using wrongly ifstream::ignore().
Extracts characters from the input sequence and discards them, until
either n characters have been extracted, or one compares equal to
delim.
file_name.ignore(1, '\n'); always dismiss the first letter. In your case, the first letter after ";" in line.

file_name.ignore(1, '\n'); will make the stream ignore one character from the input.
From reading your code:
For what you call "the 0 part", ignore is not called yet before the first getline in the loop.
For "parts 1/2/3", the ignore statement makes the stream skip the next character
For the remaining parts, there is either a space or a '\n' that was skipped so that the readable letter was not skipped.

Related

C++ Reading data from a file (containing spaces) line by line

I'm programming a game on a board 9x9 (which is a char 9x9 array). I wrote a method that saves the current game state in a file going according to the scheme bellow:
board.plansza[0][0]
board.plansza[0][1]
board.plansza[0][2]
board.plansza[0][3]
(...)
*points in int*
(Where every line is just a one character/space/number)
Now I need a method that's gonna read this file and put the data back in the same kind of array (if someone decided to stop playing, saved the game and then wanted to continue from previous state) as well as the variable for points.
The problem is that some of the lines in a saved file are just a space (' ') and all the methods I've tried are failing to read it properly because of that.
The latest way I tried (and failed):
for (int i = 0; i < ROZMIAR; i++){
for (int j = 0; j < ROZMIAR; j++){
zapis << board.plansza[i][j] << endl;
}
}
zapis << user.pkt << endl;
How do I read a file line by line if some lines contain only a space (which I don't want to ignore)?
Use getline(), like this:
#include <fstream>
#include <string>
int main()
{
std::ifstream infile("thefile.txt");
std::string line;
char matrix[10][2];
int i = 0;
while(std::getline(infile, line))
{
std:cout << line << std::endl;
if(line .find_first_not_of(' ') != std::string::npos)
{
// There's a non-space.
matrix[i++][0] = line[0];
}
}
return 0;
}

Why is the next line not executing C++

I have attached my full source code of my program that can open a .txt file. It doesn't execute after the cout << length. I am trying to store the .txt file information in memory by using an array.
#include <iostream>
#include <string.h>
#include <fstream>
using namespace std;
char filename[128];
char file[10][250];
int count;
int length;
string line;
int main ()
{
int count = 0;
int length = 0;
cout << "Filename: ";
cin.clear();
cin.getline(filename, sizeof(filename));
string new_inputfile(filename);
ifstream inputfiles (new_inputfile.c_str());
if(!inputfiles.is_open())
{
cout << "File could not be opened. \n ";
}
else
{
for (int i=0; getline(inputfiles,line); i++)
{
length++;
}
cout << length;
// char file[length][250]; <- How can I create the array based on the length variable?
// CODE DOES NOT EXECUTE AFTER THIS.
while(!inputfiles.eof() && (count<10))
{
inputfiles.getline(file[count],250);
count++;
}
for(int i=0; i < count; i++)
{
cout << file[i] << endl;
}
}
inputfiles.close();
return 0;
}
Also, since file[] is char, say for example file[1] contained the char Name=Mike, how do I strip off everything before the =. I want just Mike. I know with string, I can use substr() method, but I don't know for char.
This is horribly wasteful way to count number of lines in a file.
for (int i=0; getline(inputfiles,line); i++) // i is also completely useless here
{
length++;
}
You're reading the whole file only to throw everything away and start again! And after this loop is done, inputfiles.eof() will be true and you'll never enter neither the next while loop nor the last for loop (because i == count). Execution skips directly to inputfiles.close() and then you return from main.
I suggest you work on the line string as you go:
for ( ; getline(inputfiles, line); )
{
// do stuff with line and ditch the global char arrays
}
If you want store the lines for later, well, just save them :) The easiest thing to do is to use a vector:
std::vector<std::string> all_them_lines;
while (getline(file, line) all_them_lines.emplace_back(line);
There, the entire file is now saved in all_them_lines, line by line. You can access them just like you would in an array, like all_them_lines[0]. You also don't need to know the number of lines beforehand - vectors expand automatically when you add stuff to them.
Now to parse a line and extract formatted input from it, check out what stringstream class has to offer.
You asked:
// char file[length][250]; <- How can I create the array based on the length variable?
Declare file as:
char (*file)[250] = NULL;
and then,
file = new char[length][250];
Make sure you call delete [] file before the end of the function.
You said:
// CODE DOES NOT EXECUTE AFTER THIS.
You can rewind the stream and start reading from it again.
inputfiles.seekg(0);
count = 0;
while(!inputfiles.eof())
{
inputfiles.getline(file[count],250);
count++;
}

Read input file word by word [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I will first off say that yes, this is a homework assignment, but my teacher is really not too clear on how to do things.
I'm asked to, in c++, Write a function that will pass words from a file one at a time. The function will calculate the word length and then print out TO SCREEN the word and its length on its own line.
The main will open your input file, read it word by word in a loop and then pass the word into your function for it to be printed.
I know how to open a file using fstream and all that, read it word by word, but not in a loop or a function by the void readfile () one. My problem here is putting everything together.
This is my program to open a file, get the length and display it in a parallel array
//declare parallel arrays
string words [MAXSIZE];
//open files
outputFile.open("output.txt");
inputFile.open ("/Users/cathiedeane/Documents/CIS 22A/Lab 4/Lab 4 Part 2/lab4.txt");
//inputvalidation
while (!inputFile.eof())
{
for(int i = 0; i < MAXSIZE; ++i)
{
outputFile << words[i] << " " << endl;
inputFile >> words[i];
}
inputFile.close();
}
for (int i= 0; i <= MAXSIZE; i++)
{ cout << words[i] << ":" << words[i].size()<< endl;
outputFile << endl;
}
//close outputfile
outputFile.close();
return 0;
}
So basically your assignment is :
function read_word
/* what you have to work on */
end
function read_file_word_by_word
open file
while not end_of_file
word = read_word
print word, word_length
end
close file
end
To read a word, you need to define what it is. Usually it's a bunch of letters, delimited by other characters that are not letters (whitespace, commas, etc.).
You could read the file character by character and store them when they are letters until you encounter some other kind of character. What you have stored is a word, and you can get its length quite easily.
Tip: http://www.cplusplus.com/reference/istream/istream/get/ allows you to read a single character from a file.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
void func(const string& word)
{
//set field width
cout.width(30);
cout << left << word << " " << word.size() << endl;
}
int main(int argc, char* argv[])
{
ifstream ifs("F:\\tmp\\test.txt");
if(ifs.fail())
{
cout << "fail to open file" << endl;
return -1;
}
_Ctypevec ct = _Getctype();
for(char ch = 0; ch < SCHAR_MAX; ch++)
{
//set all punctuations as field separator of extraction
if(ispunct(ch))
{
(const_cast<short*>(ct._Table))[ch] = ctype<char>::space;
}
}
//change the default locale object of ifstream
ifs.imbue(locale(ifs.getloc(), new ctype<char>(ct._Table)));
string word;
while(ifs >> word)
{
func(word);
}
ifs.close();
}
You'll obviously want to separate each word in to its own string index to store them in your array. To separate each word, establish a break point like char break = ' '; Then, while your IOStream is reading the file, just add the words to the index using an iterator (i++)
Now that some time has passed since you asked the question, I would like to add that this could be answered in a quite small amount of code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void printString( const string & str ) { // ignore the & for now, you'll get to it later.
cout << str << " : " << str.size() << endl;
}
int main() {
ifstream fin("your-file-name.txt");
if (!fin) {
cout << "Could not open file" << endl;
return 1;
}
string word; // You only need one word at a time.
while( fin >> word ) {
printString(word);
}
fin.close();
}
A small note on fin >> word, this expression returns true for as long as there was a word read into the string. It will also skip any whitespace (tab, space and newline) by default.

HW Help: get char instead of get line C++

I wrote the code below that successfully gets a random line from a file; however, I need to be able to modify one of the lines, so I need to be able to get the line character by character.
How can I change my code to do this?
Use std::istream::get instead of std::getline. Just read your string character by character until you reach \n, EOF or other errors. I also recommend you read the full std::istream reference.
Good luck with your homework!
UPDATE:
OK, I don't think an example will hurt. Here is how I'd do it if I were you:
#include <string>
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
static std::string
answer (const string & question)
{
std::string answer;
const string filename = "answerfile.txt";
ifstream file (filename.c_str ());
if (!file)
{
cerr << "Can't open '" << filename << "' file.\n";
exit (1);
}
for (int i = 0, r = rand () % 5; i <= r; ++i)
{
answer.clear ();
char c;
while (file.get (c).good () && c != '\n')
{
if (c == 'i') c = 'I'; // Replace character? :)
answer.append (1, c);
}
}
return answer;
}
int
main ()
{
srand (time (NULL));
string question;
cout << "Please enter a question: " << flush;
cin >> question;
cout << answer (question) << endl;
}
... the only thing is that I have no idea why do you need to read string char by char in order to modify it. You can modify std::string object, which is even easier. Let's say you want to replace "I think" with "what if"? You might be better off reading more about
std::string and using find, erase, replace etc.
UPDATE 2:
What happens with your latest code is simply this - you open a file, then you get its content character by character until you reach newline (\n). So in either case you will end up reading the first line and then your do-while loop will terminate. If you look into my example, I did while loop that reads line until \n inside a for loop. So that is basically what you should do - repeat your do-while loop for as many times as many lines you want/can get from that file. For example, something like this will read you two lines:
for (int i = 1; i <= 2; ++i)
{
do
{
answerfile.get (answer);
cout << answer << " (from line " << i << ")\n";
}
while (answer != '\n');
}

Reading a file into an array

I would like to read a text file and input its contents into an array. Then I would like to show the contents of the array in the command line.
My idea is to open the file using:
inFile.open("pigData.txt")
And then to get the contents of the file using:
inFile >> myarray [size]
And then show the contents using a for loop.
My problem is that the file I am trying to read contain words and I don't know how to get a whole word as an element in the array. Also, let's say that the words are divided by spaces, thus:
hello goodbye
Could be found on the file. I would like to read the whole line "hello goodbye" into an element of a parallel array. How can I do that?
Should be pretty straightforward.
std::vector<std::string> file_contents;
std::string line;
while ( std::getline(inFile,line) )
file_contents.push_back(line);
std::vector<std::string>::iterator it = file_contents.begin();
for(; it!=file_contents.end() ; ++it)
std::cout << *it << "\n";
Edit:
Your comment about having "hello goodbye" as element zero and element one is slightly confusing to me. The above code snip will read each line of the file and store that as an individual entry in the array 'file_contents'. If you want to read it and split it on spaces that is slightly different.
For context, you could have provided a link to your previous question, about storing two lists of words in different languages. There I provided an example of reading the contents of a text file into an array:
const int MaxWords = 100;
std::string piglatin[MaxWords];
int numWords = 0;
std::ifstream input("piglatin.txt");
std::string line;
while (std::getline(input, line) && numWords < MaxWords) {
piglatin[numWords] = line;
++numWords;
}
if (numWords == MaxWords) {
std::cerr << "Too many words" << std::endl;
}
You can't have one parallel array. For something to be parallel, there must be at least two. For parallel arrays of words, you could use a declarations like this:
std::string piglatin[MaxWords];
std::string english[MaxWords];
Then you have two options for filling the arrays from the file:
Read an entire line, and the split the line into two words based on where the first space is:
while (std::getline(input, line) && numWords < MaxWords) {
std::string::size_type space = line.find(' ');
if (space == std::string::npos)
std::cerr << "Only one word" << std::endl;
piglatin[numWords] = line.substr(0, space);
english[numWords] = line.substr(space + 1);
++numWords;
}
Read one word at a time, and assume that each line has exactly two words on it. The >> operator will read a word at a time automatically. (If each line doesn't have exactly two words, then you'll have problems. Try it out to see how things go wrong. Really. Getting experience with a bug when you know what the cause is will help you in the future when you don't know what the cause is.)
while (input && numWords < MaxWords) {
input >> piglatin[numWords];
input >> english[numWords];
++numWords;
}
Now, if you really one one array with two elements, then you need to define another data structure because an array can only have one "thing" in each element. Define something that can hold two strings at once:
struct word_pair {
std::string piglatin;
std::string english;
};
Then you'll have just one array:
word_pair words[MaxWords];
You can fill it like this:
while (std::getline(input, line) && numWords < MaxWords) {
std::string::size_type space = line.find(' ');
if (space == std::string::npos)
std::cerr << "Only one word" << std::endl;
words[numWords].piglatin = line.substr(0, space);
words[numWords].english = line.substr(space + 1);
++numWords;
}
Notice how the code indexes into the words array to find the next word_pair object, and then it uses the . operator to get to the piglatin or english field as necessary.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
int main()
{
// This will store each word (separated by a space)
vector<string> words;
// Temporary variable
string buff;
// Reads the data
fstream inFile("words.txt");
while(!inFile.eof())
{
inFile>>buff;
words.push_back(buff);
}
inFile.close();
// Display
for(size_t i=0;i<words.size();++i) cout<<words[i]<<" ";
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main ()
{
vector<string> fileLines;
string line;
ifstream inFile("pigData.txt");
if ( inFile.is_open() ) {
while ( !inFile.eof() ) {
getline(inFile, line);
fileLines.push_back(line);
}
inFile.close();
} else {
cerr << "Error opening file" << endl;
exit(1);
}
for (int i=0; i<fileLines.size(); ++i) {
cout << fileLines[i] << "\n";
}
cout << endl;
return 0;
}