error reading data from input file to array - c++

The input file contains 14 state initials (TN,CA,NB,FL,etc..) that is to be rad into the array. The code below clears compiler but when i tell the program the filename it shoots out a bunch of blank spaces with two spaces containing some fuzz and a third contain a '#' symbol. i assume the problem is with my function not entirely sure what specifically though any help greatly appreciated!
input file set up with state initials one on top of the other:
TN
PA
KY
MN
CA
and so on
void readstate( ifstream& input, string []);
int main()
{
string stateInitials[14];
char filename[256];
ifstream input;
cout << "Enter file name: ";
cin >> filename;
input.open( filename );
if ( input.fail())
{
cout << " file open fail" << endl;
}
readstate ( input, stateInitials);
input.close();
return (0);
}
void readstate ( ifstream& input, string stateInitials[])
{
int count;
for ( count = 0; count <= MAX_ENTRIES; count++)
{
input >> stateInitials[count];
cout << stateInitials[count] << endl;
}
}

You are treating a character array as though it were a string array.
While you can hack put the strings next to each other inside the same char array, that is not the standard way it is done. Here is a modified version of your code, which creates one char[] to hold each initial.
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <string.h>
#define MAX_ENTRIES 14
using namespace std;
void readstate( ifstream& input, char* []);
int main()
{
char** stateInitials = new char*[14];
char filename[256];
ifstream input;
cout << "Enter file name: ";
cin >> filename;
input.open( filename );
if ( input.fail())
{
cout << " file open fail" << endl;
}
readstate ( input, stateInitials);
// After you are done, you should clean up
for ( int i = 0; i <= MAX_ENTRIES; i++) delete stateInitials[i];
delete stateInitials;
return (0);
}
void readstate ( ifstream& input, char* stateInitials[])
{
int count;
string temp_buf;
for ( count = 0; count <= MAX_ENTRIES; count++)
{
stateInitials[count] = new char[3];
input >> temp_buf;
memcpy(stateInitials[count], temp_buf.c_str(), 3);
cout << stateInitials[count] << endl;
}
}

Related

when i try to add a file to another file weird symbols appear?

when appending a file to another weird symbols appear at the end and it's ascii is -1, and if there another way to add a file to the other please share
void AddFile(char old_name[],char old_content[]) {
ofstream old_file;
ifstream new_file;
char new_name[255];
int len, f_begin, f_end;
cout << "Enter the file name: ";
cin.ignore();
cin.getline(new_name,255,'\n');
strcat(new_name, ".txt");
new_file.open(new_name);
f_begin = new_file.tellg();
new_file.seekg(0,ios::end);
f_end = new_file.tellg();
new_file.seekg(0);
len = f_end - f_begin;
char new_content[len+1];
new_content[len] = '\0';
for (int i=0; i< len; ++i) {
new_content[i] = new_file.get();
}
new_file.close();
strcat(old_content,"\n");
strcat(old_content,new_content);
old_file.open(old_name);
cout << old_content;
old_file << old_content;
old_file.close();
}
the .tellg() function gives the correct size
I have written just a snippet of code to help you in the right direction. You can use it or modify as needed.
#include <iostream>
#include <fstream>
using namespace std;
void AddFile(char old_name[], char old_content[]) {
ofstream old_file;
ifstream new_file;
char new_name[255];
int len, f_begin, f_end;
cout << "Enter the file name: ";
/*cin.ignore();
cin.getline(new_name, 255, '\n');*/
cin >> new_name;
strcat(new_name, ".txt");
new_file.open(new_name);
old_file.open(old_name, ios::ios_base::app);
char line[65535];
while (new_file.getline(line, 65535))
{
old_file << endl << line;
}
new_file.close();
old_file.close();
//verify new data
new_file.open(old_name);
while (new_file.getline(line, 65535))
{
cout << line << endl;
}
}
void main()
{
AddFile("hello.txt", "old data");
}
I might be able to better help if you can share your use case for it.

Is it possible to use an outputfile as an inputfile later on in code (C++ I/O files)

So what I did was this;
ifstream infile("warehouse.txt"); ffile("updated.txt");
ofstream outfile("updated.txt");
basically what I want to do is read from the inputfile 'warehouse.txt' and store contents in an array and then add this array and an extra array to outputfile 'updated.txt'.
Then I want to use 'updated.txt' as an input file as shown in the code above is this allowed, I basically want to store all the data on updated.txt into one big array i.e combine the two arrays, is this allowed? I tried it and my compiler seemed to screw up and I was reading about using vectors instead but am struggling to understand them. thanks.
here is my overall code what I wanted to do was basically take from an input file the 'fruitname' and its corresponding quantity from an input file. store extra entries in an extraarray and then put both these arrays in an output file as stated above and then use that output as an input file so I can aggreagte the data.
THE PROBLEM:
When I try to store from the updated.txt to array my cout's show that I get random numbers in place of what should be the fruitname and its number.
#include <iostream>
#include <string>
#include <cstdlib>
#include <fstream>
using namespace std;
typedef struct items {
string name;
int quantity;
} items_t;
void fileopenchecker (ifstream &FILE);
int readfromfile (ifstream &FILE, items_t fruit[]);
int extrarray (items_t fruit[]);
void writetooutputfile (ofstream &OFILE, items_t fruit[], int size);
void combinearrays (ifstream &final, items_t overallfruit[], int total);
int main()
{
const int MAX_SIZE = 150;
int Nfruit = 0;
int Nextrafruit = 0;
int total;
std::ifstream infile("warehouse.txt");
std::ofstream outfile("updated.txt");
std::ifstream ffile("updated.txt");
items_t extrafruit[MAX_SIZE], fruit[MAX_SIZE], overallfruit[MAX_SIZE];
fileopenchecker(infile);
Nextrafruit = extrarray(extrafruit);
Nfruit = readfromfile(infile, fruit);
total = Nextrafruit + Nfruit;
infile.close();
writetooutputfile(outfile, fruit, Nfruit);
writetooutputfile(outfile, extrafruit, Nextrafruit);
combinearrays (ffile, overallfruit, total);
ffile.close();
return 0;
}
void combinearrays (ifstream &final, items_t overallfruit[], int total){
int i;
for(i=0; i<total; i++){
final >> overallfruit[i].name >> overallfruit[i].quantity;
cout << overallfruit[i].name << overallfruit[i].quantity << endl;
}
}
void fileopenchecker (ifstream &FILE){
if(!FILE.is_open()){
cout << "Your file was NOT detected!" << endl;
exit(1);
}
else{
cout << "Your file was detected" << endl;
}
}
int readfromfile (ifstream &FILE, items_t fruit[]){
int entries = 0;
while(!FILE.eof()){
FILE >> fruit[entries].name >> fruit[entries].quantity;
cout << fruit[entries].name << fruit[entries].quantity << endl;
entries++;
}
return entries;
}
int extrarray (items_t fruit[]){
int runner=1, exentries =0;
while(runner==1){
cout << "Would you like to add entries to your file? (YES-->1 NO-->0)" << endl;
cin >> runner;
if(runner==0){
break;
}
//take the itemname and quantity and stores it in the array.
cout << "Enter the name of the fruit and its quantity" << endl;
cin >> fruit[exentries].name >> fruit[exentries].quantity;
//debugging:
cout << fruit[exentries].name << fruit[exentries].quantity << endl;
exentries++;
}
return exentries;
}
void writetooutputfile (ofstream &OFILE, items_t fruit[], int size){
int entries = 0;
while(entries < size){
cout << fruit[entries].name << fruit[entries].quantity << endl;
OFILE << fruit[entries].name << fruit[entries].quantity << endl;
entries++;
}
}
"I want to do is read from the inputfile 'warehouse.txt'"
{
std::ifstream ifs("warehouse.txt");
// reading from ifs ...
... "to outputfile 'updated.txt'"
std::ofstream ofs("updated.txt");
// writing to ofs ...
}
... "Then I want to use 'updated.txt' as an input file" ~> create another instance of ifstream:
{
std::ifstream ifs2("updated.txt");
// reading from ifs2 ...
}
Yes, and it's possible to to use just two file streams if you use std::fstream. For example:
#include <fstream>
#include <iostream>
#include <string>
int main(void)
{
std::ifstream infile("a.txt");
// create file for both reading and writing
std::fstream ffile("b.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
// read contents of file a and write to file b
std::string line;
while (std::getline(infile, line))
{
std::cout << line << std::endl;
ffile << line << std::endl;
}
// flush the output to disk
ffile.flush();
// go back to the start of the output file before reading from it
ffile.seekg(0);
// read contents of output file again.
while (std::getline(ffile, line))
{
std::cout << line << std::endl;
}
return 0;
}

Trying to read a file into a char array

I am trying to read all the characters in a file into an array. Assuming all variables are declared, why are all the characters not being read into my array. When I output some of the characters in the "storeCharacters[]" array, garbage is being returned. Please help.
This is my function:
void countChars(ifstream& input, char storeCharacters[])
{
int i = 0;
while( !input.eof() )
{
input.get(storeCharacters[i]);
i++;
}
}
After the while loop try adding storeCharacters[i] = '\0' to null terminate the string.
The easy fix to your problem if you know the maximum size of your file, then just set your array to have that size and initialize it with \0.
let's say the maximum characters count in your file is 10000.
#define DEFAULT_SIZE 10000
char storeCharacters[DEFAULT_SIZE];
memset (storeCharacters,'\0',DEFAULT_SIZE) ;
The below post should be the correct way to read a file using a buffer it has memory allocation and all what you need to know :
Correct way to read a text file into a buffer in C?
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
void getFileName(ifstream& input, ofstream& output) //gets filename
{
string fileName;
cout << "Enter the file name: ";
cin >> fileName;
input.open(fileName.c_str());
if( !input )
{
cout << "Incorrect File Path" << endl;
exit (0);
}
output.open("c:\\users\\jacob\\desktop\\thomannProj3Results.txt");
}
void countWords(ifstream& input) //counts words
{
bool notTrue = false;
string words;
int i = 0;
while( notTrue == false )
{
if( input >> words )
{
i++;
}
else if( !(input >> words) )
notTrue = true;
}
cout << "There are " << i << " words in the file." << endl;
}
void countChars(ifstream& input, char storeCharacters[], ofstream& output) // counts characters
{
int i = 0;
while( input.good() && !input.eof() )
{
input.get(storeCharacters[i]);
i++;
}
output << storeCharacters[0];
}
void sortChars() //sorts characters
{
}
void printCount() //prints characters
{
}
int main()
{
ifstream input;
ofstream output;
char storeCharacters[1000] = {0};
getFileName(input, output);
countWords(input);
countChars(input, storeCharacters, output);
return 0;
}

Reading information into array of structs c++

I'm making a program for my c++ class. Ultimately I want my program to perform a quicksort on a text file of contacts in the following format:
Firstname Secondname Number
Each contact is separated by a new line. I've started by counting the number of lines and using dynamic memory allocation to create an array of structs which has the same size as the number of lines.
However, when I tried to read in the information from the text file and output it to the screen, all I get is gibberish. I've had a look around on the internet to try and find a solution but everything I've found seems to use a different syntax to me.
Here's my code so far:
#include <iostream>
#include <fstream>
#include <istream>
char in[20];
char out[20];
using namespace std;
struct contact
{
char firstName[14];
char surName[14];
char number[9];
};
//structure definition
int main(void){
cout << "Please enter the input filename: " << endl;
cin >> in;
ifstream input(in);
if(!input){
cerr << "failed to open input file " << in << endl;
exit(1);
}
cout << "Please enter tne output filename: " << endl;
cin >> out;
// read in the input and output filenames
char a;
int b=0;
while (input.good ())
{
a=input.get ();
if (a=='\n')
{
b++;
}
}
// count the number of lines in the input file
input.seekg (0, ios::beg);
//rewind to beginning of file
contact* list = new contact[b];
//dynamically create memory space for array of contacts
int i = 0.;
while(input){
if(i >= b) break;
if(input >> *list[i].firstName >> *list[i].surName >> *list[i].number) i++;
else break;
}
input.close();
//read information from input file into array of contacts
for(int N = 0; N < b; N++){
cout << list[N].firstName << list[N].surName << list[N].number << endl;
}
ofstream output(out);
int k = 0;
for(int k = 0; k<b; k++){
output << list[k].firstName << " " << list[k].surName << " " << list[k].number << endl;
}
//print out the unsorted list to screen and write to output file
//i've done both here just to check, won't print to screen in final version
output.close();
delete []list;
} // end of main()
You reset the files location to the beginning, but the files eofbit is still labeled as true from when you first read the amount of lines. A quick fix to this is re-opening the file after you read the lines, possibly making the line count a function to clean up code.
int lines(const string path)
{
ifstream tmp(path.c_str());
string temp;
int count = 0;
getline(inFile,temp);
while(inFile)
{
count++;
getline(inFile,temp);
}
tmp.close();
return count;
}
Okay, I put together a quick and dirty method using newer C++ constructs to get you most of the way there. You're on your own for writing to the file (trivial) and the quicksort, though I've put the struct into a vector for you, so sorting the vector is as easy as writing a custom function to compare one struct vs the other. I apologize in advance if some of the code is less than canonical C++. I'm way past my bed time, and way tired, but this was interesting enough of a problem that I wanted to give it a go. Happy coding!
#include <iostream>
#include <fstream>
#include <istream>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
#include <sstream>
using namespace std;
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while(std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
return split(s, delim, elems);
}
struct contact
{
std::string firstName;
std::string surName;
std::string number;
contact(std::string& fName, std::string& lName, std::string& num) : firstName(fName), surName(lName), number(num) {}
};
//structure definition
char in[20];
char out[20];
int main()
{
std::vector<contact> contacts;
cout << "Please enter the input filename: " << endl;
cin >> in;
ifstream input(in);
if(!input){
cerr << "failed to open input file " << in << endl;
exit(1);
}
cout << "Please enter tne output filename: " << endl;
cin >> out;
std::string sinput;
// read in the input and output filenames
while (input.good ())
{
getline(input, sinput);
vector<string> tokens = split(sinput, ' ');
if (tokens.size() == 3)
{
contact c(tokens[0], tokens[1], tokens[2]);
contacts.push_back(c);
}
}
input.close();
//read information from input file into array of contacts
std::cout << "Outputting from vector..." << std::endl;
for_each(contacts.begin(), contacts.end(), [](contact& c) {
cout << c.firstName << " " << c.surName << " " << c.number << endl;
});
return 0;
}
Also, just want to give credit that the split methods come from this answer on this very site. Cheers!

C++ program to read a txt file and sort data

I'm a physics PhD student with some experience coding in java, but I'm trying to learn C++.
The problem I'm trying to solve is to read in data from a .txt file and then output all the numbers > 1000 in one file and all those <1000 in another.
What I need help with is writing the part of the code which actually reads in the data and saves it to an array. The data itself is only separated by a space, not all on a new line, which is confusing me a bit as I don't know how to get c++ to recognise each new word as an int. I have canabalised some code I have got from various sources online-
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
#include<cmath>
using namespace std;
int hmlines(ifstream &a) {
int i=0;
string line;
while (getline(a,line)) {
cout << line << endl;
i++;
}
return i;
}
int hmwords(ifstream &a) {
int i=0;
char c;
a >> noskipws >> c;
while ((c=a.get()) && (c!=EOF)){
if (c==' ') {
i++;
}
}
return i;
}
int main()
{
int l=0;
int w=0;
string filename;
ifstream matos;
start:
cout << "Input filename- ";
cin >> filename;
matos.open(filename.c_str());
if (matos.fail()) {
goto start;
}
matos.seekg(0, ios::beg);
w = hmwords(matos);
cout << w;
/*c = hmchars(matos);*/
int RawData[w];
int n;
// Loop through the input file
while ( !matos.eof() )
{
matos>> n;
for(int i = 0; i <= w; i++)
{
RawData[n];
cout<< RawData[n];
}
}
//2nd Copied code ends here
int On = 0;
for(int j =0; j< w; j++) {
if(RawData[j] > 1000) {
On = On +1;
}
}
int OnArray [On];
int OffArray [w-On];
for(int j =0; j< w; j++) {
if(RawData[j]> 1000) {
OnArray[j] = RawData[j];
}
else {
OffArray[j] = RawData[j];
}
}
cout << "The # of lines are :" << l
<< ". The # of words are : " << w
<< "Number of T on elements is" << On;
matos.close();
}
But if it would be easier, i'm open to starting the whole thing again, as I don't understand exactly what all the copied code is doing. So to summarise, what I need is it to-
Ask for a filepath in the console
Open the file, and store each number (separated by a space) as an element in a 1D array
I can manage the actual operations myself I think, if I could just get it to read the file the way I need.
Thanks very much
Using C++11 and the Standard Library makes your task fairly simple. This uses Standard Library containers, algorithms, and one simple lambda function.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::string filename;
std::cout << "Input filename- ";
std::cin >> filename;
std::ifstream infile(filename);
if (!infile)
{
std::cerr << "can't open " << filename << '\n';
return 1;
}
std::istream_iterator<int> input(infile), eof; // stream iterators
std::vector<int> onvec, offvec; // standard containers
std::partition_copy(
input, eof, // source (begin, end]
back_inserter(onvec), // first destination
back_inserter(offvec), // second destination
[](int n){ return n > 1000; } // true == dest1, false == dest2
);
// the data is now in the two containers
return 0;
}
Just switch the type of variable fed to your fistream, created from new std:ifstream("path to file") into a int and c++ will do the work for you
#include <fstream> //input/output filestream
#include <iostream>//input/output (for console)
void LoadFile(const char* file)
{
int less[100]; //stores integers less than 1000(max 100)
int more[100]; //stores integers more than 1000(max 100)
int numless = 0;//initialization not automatic in c++
int nummore = 0; //these store number of more/less numbers
std::ifstream File(file); //loads file
while(!file.eof()) //while not reached end of file
{
int number; //first we load the number
File >> number; //load the number
if( number > 1000 )
{
more[nummore] = number;
nummore++;//increase counter
}
else
{
less[numless] = number;
numless++;//increase counter
}
}
std::cout << "number of numbers less:" << numless << std::endl; //inform user about
std::cout << "number of numbers more:" << nummore << std::endl; //how much found...
}
This should give you an idea how should it look like(you shoudnt use static-sized arrays tough) If you got any probs, comment back
Also, please try to make nice readable code, and use tabs/ 4 spaces.
even though its pure C, this might give you some hints.
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#define MAX_LINE_CHARS 1024
void read_numbers_from_file(const char* file_path)
{
//holder for the characters in the line
char contents[MAX_LINE_CHARS];
int size_contents = 0;
FILE *fp = fopen(file_path, "r");
char c;
//reads the file
while(!feof(fp))
{
c = fgetc(fp);
contents[size_contents] = c;
size_contents++;
}
char *token;
token = strtok(contents, " ");
//cycles through every number
while(token != NULL)
{
int number_to_add = atoi(token);
//handle your number!
printf("%d \n", number_to_add);
token = strtok(NULL, " ");
}
fclose(fp);
}
int main()
{
read_numbers_from_file("path_to_file");
return 0;
}
reads a file with numbers separated by white space and prints them.
Hope it helps.
Cheers