I'm trying to make a program that reads input from a file (it is named grades.txt) and make an output of (image attached)
Apparently, I'm converting strings to char arrays and my program's output quite unexpected (image attached) I have checked twice, the IDE doesn't show any errors as well.
I'm using this as the source code.
#pragma warning(disable:4996)
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
//Author: Hidden for privacy
const int MAXNAME = 20;
int main()
{
ifstream inData;
inData.open("grades.txt");
string rawInputString;
char name[MAXNAME 1]; // holds student name
float average; // holds student average
inData.get(name, MAXNAME 1);
while (inData)
{
bool firstSpace = false;
bool secondSpace = false;
char converter[23];
getline(inData, rawInputString, '\n');
strcpy(converter, rawInputString.c_str());
for (int a = 0; a <= 22; a ) {
if (converter[a] != ' ') {
cout << converter[a];
}
if (converter[a] == ' ') {
if (!firstSpace) {
firstSpace = true;
continue;
}
if (!secondSpace) {
secondSpace = true;
continue;
}
}
if (firstSpace) {
cout << converter[a];
if (secondSpace) {
cout << converter[a];
}
}
}
}
inData.close();
return 0;
}
Here is the grades.txt file:
Adara Starr 94
David Starr 91
Sophia Starr 94
Maria Starr 91
Danielle DeFino 94
Dominic DeFino 98
McKenna DeFino 92
Taylor McIntire 99
Torrie McIntire 91
Emily Garrett 97
Lauren Garrett 92
Marlene Starr 83
Donald DeFino 73
What I've tried: As seen in the source code, I tried to make the program print the output char by char. But apparently, the first few characters printed are not even in the file where the program is taking input from. I know that float average and char array name are uninitiated, but it doesn't affect the rest of the code (too much), so I'm just leaving those there. I tried reading the fstream library to maybe figure out if this was something caused by the ifstream, but that doesn't seem to be the case either.
CodePudding user response:
There are a few different problems in your code, but the main ones is that:
- You start with
inData.get(name, MAXNAME 1)
which reads only a part of the first line - You iterate over the whole array no matter its string length
- The character array
converter
is just too small to fit a full line including the null-terminator
Among the other problems is that you read from the input file before checking its status; You use while (inData)
which is not correct; You use a C-style character array when there's no need; And you forget to print a newline.
There are also better ways to handle the input and output, like using an input string stream to parse out the fields, and use standard I/O manipulators for your output.
If we put it all together I would recommend something like this instead:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
int main()
{
std::ifstream infile("grades.txt");
std::string inputline;
// Read line by line from the input, includes error checking
// Also includes checking if the file was opened or not
while (std::getline(infile, inputline))
{
// An input stream to parse out the data we need
std::istringstream parser(inputline);
std::string firstname;
std::string lastname;
int value;
parser >> firstname >> lastname >> value;
// Just construct a simple string of the name
// To simplify "pretty" output
std::string fullname = firstname ' ' lastname;
// And finally the output with the name in one column and the value in another
std::cout << std::left << std::setw(20) << fullname << value << '\n';
}
}