C++ Reading from file incorrectly - c++

There is a certain problem that I would like to have help with. Here is how it goes:
I'm using the following code to read a certain amount of characters into a char array to process later:
char str[15]; // first 16 characters that i need to get from file
std::ifstream fin("example.txt");
if(fin.is_open()){
std::cout<<"File opened successfully \n";
for(int i = 0; i<=15; i++)
{
fin.get(str[i]); //reading one character from file to array
}
}
else{
std::cout<<"Failed to open file";
}
std::cout<<str;
It works fine for the first 4 or even 5 characters, but when it reaches to 8 it starts to print out garbage characters.
Contents of the example.txt file, from which i read text.
The Quick Brown Fox Jumped Over The Lazy Dog The Quick Brown Fox Jumped Over The Lazy Dog
Output when I read 8 characters:
The Quic�j�
Output when I read 16 characters:
The Quick Brown ASCII
Why is this happening and where did the 'ASCII' come from when I try to read certain length from a file?
And lastly, what kind of code should I utilize if I want to get specific lengths from a file? For example if I want to read the first 4 or 8 or 16 or even 20 characters? It doesn't necessarily have to be into a char array, it can be saved into a string.
Thank you in advance.

Your char array is only 15 chars long. So this line goes out of bounds:
for(int i = 0; i<=15; i++)
If i is equal to 15 that's one too many because your array counts from 0 to 14.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <= count them!
There are 15 places starting at 0 ending at 14
Also when strings are stored in memory they have to be terminated by a null character '\0'. Otherwise the function that prints them doesn't know when to stop, which is probably where your garbage is coming from.
So, because the null terminator takes one of your 15 spaces, that only leaves you with 14 to read from the file.
So:
for(int i = 0; i < 14; i++)
{
fin.get(str[i]); //reading 14 characters (0-13)
}
str[14] = '\0'; // add the string terminator at the end of the array.
See if that works.

Related

How can I read from the same input file multiple times from different points within the file using sentinel values (-1) in c++?

I have a task where I have to read different sections of an input file(.txt) of integers in c++. The file contains an unknown number of positive integers, each separated by white-space with several sentinel values of -1 placed randomly in the list to "break-up" the list into sections and another -1 at the end of the file.
Here is a sample of my input file(.txt):
3 54 35 4 9 16 -1 14 57 32 4 6 8 41 2 -1 5 6 54 21 3 -1
Here is what I've attempted so far:
int data[20],
index = 0;
ifstream fin;
fin.open("data_file.txt");
while (index < 20 && data[index] != -1 && fin >> data[index])
{
cout << data[index] << endl;
index++;
}
I can't get this to read past the first SV even if I repeat this while loop. It always just starts at the beginning of the file.
How do I read again STARTING AFTER the first SV to the second SV? The only methods I know involve reading a file from beginning to end. How do I read seperate sections?
Thanks in advance for any help,
Cheers
It sounds like you just want to group information from the file. I will not provide code since you didn't, but I may help you with the logic:
Create a file object, 2d vector, and a string
Read from the file object to the string
if the value is equal to "-1", then add a new row. Else, add a new column
The result will be a 2d vector with the rows being each group, and the columns being each positive number in that group.

Two 2D Arrays, Two Matrices, One File

I am trying to figure out how to read two matrices from one file and then assign them to two different 2D arrays. The matrices are separated by a new line in the text file. I managed to get the first one to read successfully but now I cant figure out how to read the second one. The way I see it, the the line that separates the two matrices must be considered and checked for. How do I get the program to read and assign the second matrix to an array?
Both matrices and arrays are 4x4.
This is what the text file looks like:
3 4 5 7
5 16 7 12
11 12 3 9
9 8 1 12
15 4 3 6
1 12 3 12
7 8 19 9
11 12 8 5
Here is my code for the first array which works fine.
for (int y = 0; y < 4; ++y )
{
for (int x = 0; x < 4; ++x )
{
infile >> array1[x][y];
}
}
And here is my code for the array I can't figure out.
for (int y = 0; y < 4; ++y )
{
for (int x = 0; x < 4; ++x )
{
if(x == '\n' && y == '\n') //My attempt.
{
infile >> array2[x][y];
}
}
}
Here is the output:
This will check to make sure numbers in file are written to the first array.
3 4 5 7
5 16 7 12
11 12 3 9
9 8 1 12
This will check to make sure numbers in file are written to the second array.
9.21742e-314 1.0572e-307 7.29112e-304 3.87184e-306
1.06498e-307 1.65425e-317 6.79039e-313 4.22748e+266
5.92879e-323 1.06196e-307 6.95089e-308 9.88799e-315
1.79648e-313 8.48798e-314 6.95224e-308 1.06193e-307
Press any key to continue . . .
Any help is appreciated!
When you are reading your file using the "formatted input" operator >>, the kind and amount whitespace (spaces, tabs, newlines) between the items (numbers in your case) is insignificant. This means you do not get to see the empty line at all. If you need to parse a file based on its lines, consider using getline instead and parsing the single lines using a istringstream.
If on the other hand you know the size of both arrays, you can simply read the second array just as you read the first array. The extra empty line just gets ignored.
The reason your code for reading the second array does not work is that you compare the index variables to '\n', which happens to be 10 on most systems. As your index ranges from 0 to 3, the if condition is never true, so nothing gets read at all, so you are seeing a dump of uninitialized memory.
You can read the second array exactly as you read the first. The reason is that, when you start reading from a stream, at first it discards whitespaces till it encounters something that is not whitespace. Then it gets the numbers/character one by one till it encounters whitespace again. So, there is no problem with the newline and you can read the remaining array without problems.

Ifstream Read Useless Data

I'm using C++ to read a file in chunks.
The file contains integers, two per line.
First of all, I'm using this to find the file's length :
input.seekg (0, input.end);
int length = input.tellg();
input.seekg (0, input.beg);
After that, i check if length is bigger than chunksize, and if this is true, I allocate memory for the chunk...
char * buffer = new char [chunksize];
Ok, so here goes the reading function...
while (true)
{
input.read (buffer,chunksize);
cout<<buffer;
if(input.eof()) break;
}
Immediately after that I delete [] buffer;
However, I'm facing a problem with this code. For example, when the input file is like that :
2 5
4 5
6 8
7 5
4 2
1 2
The program will not output the expected characters, but something like :
2 5
4 5
6 8
7 5
4 2
1 2 2
1 2
Do you know the reason for these extra characters? If the file's size is less than chunksize, I input.read using its length and it works just fine. Maybe if using read with a length larger than the size of the file makes it not work correctly?
Thanks a lot
Your string is not NULL-terminated. The read() function will not put a '\0' at the end of what it reads for you, so when you go to print it, you're printing essentially garbage data beyond the end of what you read, because the print code is expecting a NULL terminator to mark the end of the string.

forloop lines of arrays

int lineInputs = 0;
cin >> lineInputs;
int whatever = 0;
char* myArray = new char[arrayElements*lineInputs];
int j =0;
for(int i = 0; i < lineInputs; i++)
{
cin >> whatever;
for(j; j<total; j+=39)
{
for(int nom=0; j<arrayElements; nom++)
{
cin >> myArray[j];
}
}
}
In my forloop say i have lineInputs = 4 and total = 156
Meaning 4 times we do this, we want to insert 156 chars into my array. But we want to make it so that every 40 characters we continue entering the array.
Bsically we need to insert this input into the array but i feel like my forloops are messed up. This will be the input
4
1
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
2
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
3
HHTTTHHTTTHTHHTHHTTHTTTHHHTHTTHTTHTTTHTH
4
HTHTHHHTHHHTHTHHHHTTTHTTTTTHHTTTTHTHHHHT
The first line 4 meaning 4 of these 40 character lines. And the number above the character lines just signifying line 1 2 3 4 ect.
How can i attempt this right?
So the array would basically look like this.
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTHHTTTHHTTTHTHHTHHTTHTTTHHHTHTTHTTHTTTHTHHTHTHHHTHHHTHTHHHHTTTHTTTTTHHTTTTHTHHHHT
You are making the same fundamental mistake you made in your other question, which is to fail to treat the input array correctly. You are repeatedly reading into the first 40 characters of myArray. What you need to do is read the first line into the first 40 characters, the second line into characters 40 to 79, etc.
Better yet, make it a two dimensional array so that you don't have to muck around with computing the indices.
Even better, make it an array of std::string rather than an array of char.

sorting through a file/returning info

Just need general project help.
Basically I need to do this for 8 players. The numbers come from a file im supposed to call in. The first 5 numbers for for the first 5 games, the next for rebounds, and then for blocks. Im assuming I need to call in a loop to read the first name, last name, points, rebounds and blocks, process that info and then output the information.Any tips/ suggestions?
ex from the text file:
Thomas Robinson 17 28 10 16 10 11 12 13 8 9 1 1 1 0 1
ex from what I'm supposed to return that information to
Game Log
-----------------------------------------------------------------------------
Player Name : Thomas Robinson
-----------------------------------------------------------------------------
Game # Points Rebounds Blocks
-----------------------------------------------------------------------------
1 17 11 1
2 28 12 1
3 10 13 1
4 16 8 0
5 10 9 1
-----------------------------------------------------------------------------
I think this is homework, but since I don't know which functions can be used, and which functions can't, my answers may be can't fit the request.
At a first look, I got three ideas.
1) using ifstream::get()
ifstream in_file;
in_file.open("your_file_name.txt");
char ch;
string str = "";
while(in_file.get() != '\n')
{
str = "";
while((ch = in_file.get()) != ' ')
{
// add ch to str.
str += string(&ch, 1);
}
// push str into an array, vector, stack, etc.
/*...*/
}
in_file.close();
2) read the line into a string, and then use a split function, you can find how to implement a split function everywhere.
3) use the ifstream::getline() function, it provides a delemiter parameter.
you can find the usage of ifstream::get() and ifstream::getline() here and here
The code I provide in 1) is probably not a good practice, you should check the 'EOF' stream error, in_file.open()'s exceptions etc.
btw, the code I first wrote was an error code, you can't use str += string(ch), you should either write str += string(&ch, 1) or str += string(1, ch) or str += ch you can find string's constructors here. Sorry for the error code again.
You can parse the file with the ">>" operator pretty nicely if everything is separated by spaces and newlines. Which is how the ">>" operator works. So, yes, you need a loop. Basically you want the loop to work like this:
(I never knew you could do this in Comp Sci 1. It would've saved me so much trouble...I used to do things like what the other answer is doing.)
(I'm also assuming you know how to open a txt file as an ifstream. If not, see http://www.cplusplus.com/reference/iostream/ifstream/open/.)
int temp;
int n = 0;
int x = 1;
while(textfile >> temp) // Each time through the loop, this will make temp
// the next value in the file. It will stop when
// there's nothing more to read.
{
/* Now it's going to go from left to right through the file, so you
need some logic to put it in the right place. you know that every
five numbers start a new column, so:*/
array[x][n] = temp; //Start x at 1 because you're skipping the first column
n++;
if (n == 5) {
n = 0;
x++; //Every five values, move on to the next column
}
Now your array will have the stuff where it needs to be. Just output it according to plan.