Reading Strings and Ints from the Same File - c++

Given input in the form of
fifteen,7,fourth-four,2,1,six
66,eight-six,99,eighteen
6,5,4,3,2,1
What can I use to read this into a format that I can then parse? The goal is to be able to sort the numbers and then print them back out, in order, in the same format that they were given to me. For example, the following should be printed as
1,2,six,7,fifteen,forty-four
eighteen,66,eighty-six,99
1,2,3,4,5,6
I have an idea of how the sorting should be done, I'm just having trouble figuring out the best way to read in the input. Currently, I'm using just doing this:
#include <iostream>
#include <string>
using namespace std;
int main() {
char word;
char arr[20];
int count = 0;
while (cin >> word) {
if (word == '\n') {
cout << "Newline detected.";
}
cout << "Character at: " << count << " is " << word << endl;
count++;
}
}
This does not work, because there is never a \n read in.

IMO the easiest way to do it would be to use std::istream's getline function with the ',' as the delimiter.
E.g. Something like.
char dummystr[256];
int count = 0;
while (cin.getline(dummystr, 256, ',')) {
cout << "Character at: " << count << " is " << dummystr << endl;
++count;
}
For newline delimiters with comma delimiters on each line (you really should just pick one):
char dummystr[256]; // not max size for the string
int count = 0;
while (cin.getline(dummystr, 256, '\n')) {
std::stringstream nested(dummystr);
char dummystr2[256];
while (nexted.getline(dummystr2, 256, ',')) {
cout << "Character at: " << count << " is " << dummystr << endl;
++count;
}
}

Related

String doesn't want to store a 2700 character word

I'm trying to make a program that prints all the numbers from 100-999. After that you get to choose how many numbers you want to find. Then you type the number's position and it will be outputed.
There is one problem. The string, named str, stops storing at the number 954.
Here's the code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
//Prints to myFile the numbers from 100 to 999 without a space in between. Like this: 100101102...999
ofstream myFile("numere.txt");
for(int i = 100; i <= 999; i++)
myFile << i;
//Makes the string str to store the line: 100101102103...999. But only stores until 954 (100101102..954)
ifstream myFileRead("numere.txt");
string str;
while(getline(myFileRead, str))
cout << str << endl;
//Ouputs the lenght that should be 2700 but is instead 2565
cout << endl;
cout << "String legth: " << str.size() << endl;
cout << endl;
int n, k;
cout << "Enter how many numbers do you want to find: ";
cin >> n;
for(int i = 1; i <= n; i++){
cout << "Enter number position(it starts from 0) : ";
cin >> k;
cout << "Here's the number on position " << k << ": " << str.at(k);
cout << endl;
}
system("pause>0");
}
Thanks for your attention. I’m looking forward to your reply.
C++ streams are buffered. When you use << to write to a file it is not immediately written to the file.
Try to close or flush the ofstream before you read from it:
myFile.close(); // or...
myFile.flush();
For more details I refer you to flush() and close().
PS: Actually it is rather rare that you need to close a fstream explicitly. You wouldn't need to do it when you used seperate functions for writing and reading:
void write_to_file() {
std::ofstream myFile("numere.txt");
//...
}
void read_from_file() {
std::istream myFile("numere.txt");
//...
}
Because the destructor of ofstream already closes the file.

How do I extract an integer from a file between two characters?

I want to extract an specific number from a file which contains lines that look like this (the line goes on, this is the only important part):
"https://stackoverflow.com/questions/ask?wizard=1";
Where I have to ignore until I find the character '=' with a f.ignore(MAX_LONG_LINE, '\n'). But when it comes to getting the number 1 (it could be any number) in the url, I don't know what to do.
I've tried with getline(f, num, '"') but that doesn't support integers and converting from string to int is too advanced for what I'm learning and what my course is. There has to be a simpler method. After that, I tried with f >> num but that skips until the next space instead of the '"'.
num should result in the number between '=' and '"' in a file, which in the example is 1 but it could be different.
Thanks in advance
can be :
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main(int argc, char ** argv)
{
if (argc != 2) {
cout << "usage : " << argv[0] << " <file path>" << endl;
return -1;
}
ifstream in(argv[1]);
if (!in) {
cout << "cannot open " << argv[1] << endl;
return -1;
}
string line;
in >> line;
size_t p = line.rfind('=');
if (p == string::npos) {
cout << "invalid line '" << line << "', = is missing" << endl;
return -1;
}
stringstream ss(line.substr(p + 1));
int n;
string s;
ss >> n >> s;
if (s != "\";") {
cout << "invalid line '" << line << "', must be ...<number>\";'" << endl;
return -1;
}
cout << "number is " << n << endl;
return 0;
}
I ended up solving this myself:
Turns out f >> num does work, I just needed to add one more ignore before doing it, as it was getting the previous number. If you're having issues with this I suggest you to check you're correctly positioned with f.ignore(MAX_LONG_LINE, '\n') or similar methods before anything else. As long as num is an integer, it will extract a value of the same type.
Thanks a lot to everyone who helped me.

Using C++ Fstream to output numbers from text file - Need help separating lines

I need to create a program that takes integers from a text file, and outputs them, including the number, lowest number, largest number, average, total, N amount of numbers, etc. I can do this just fine with the code below, but I also need to process the text per line. My sample file has 7 numbers delimited with tabs per row, with a total of 8 rows, but I am to assume that I do not know how many numbers per row, rows per file, etc. there are.
Also, for what it's worth, even though I know how to use vectors and arrays, the particular class that I'm in has not gotten to them, so I'd rather not use them.
Thanks.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
int num;
int count = 0;
int total = 0;
int average = 0;
string str = "";
int numLines = 0;
int lowNum = 1000000;
int highNum = -1000000;
ifstream fileIn;
fileIn.open("File2.txt");
if (!fileIn) {
cout << "nError opening file...Closing program.n";
fileIn.close();
}
else {
while (!fileIn.eof()) {
fileIn >> num;
cout << num << " ";
total += num;
count++;
if (num < lowNum) {
lowNum = num;
}
if (num > highNum) {
highNum = num;
}
}
average = total / count;
cout << "nnTotal is " << total << "." << endl;
cout << "Total amount of numbers is " << count << "." << endl;
cout << "Average is " << average << "." << endl;
cout << "Lowest number is " << lowNum << endl;
cout << "Highest number is " << highNum << endl;
fileIn.close();
return 0;
}
}
One way to deal with the individual lines is to skip leading whitespaces before reading each value and to set the stream into fail-state when a newline is reached. When the stream is good after skipping and reading a value, clearly, there was no newline. If there was a newline, deal with whatever needs to happen at the end of a line, reset the stream (if the failure wasn't due to reaching eof()) and carry on. For example, the code for a loop processing integers and keeping track of the current line could like this:
int line(1);
while (in) {
for (int value; in >> skip >> value; ) {
std::cout << "line=" << line << " value=" << value << '\n';
}
++line;
if (!in.eof()) {
in.clear();
}
}
This code uses the custom manipulator skip() which could be implemented like this:
std::istream& skip(std::istream& in) {
while (std::isspace(in.peek())) {
if (in.get() == '\n') {
in.setstate(std::ios_base::failbit);
}
}
return in;
}

C++ iteration, file i/o

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
int main()
{
//Input .txt file
ifstream inputFile ("input.txt");
try
{
int i = 1; //Line iterator
int vertices = 0;
int faces = 0;
string line;
while (getline(inputFile, line))
{
//Take number from line 4, set as variable "vertices"
if (i == 3)
{
getline (inputFile,line);
size_t last_index = line.find_last_not_of("0123456789");
string str = line.substr(last_index);
vertices = atoi(str.c_str()); //Convert to int
cout << "vertices " + str << endl;
}
//Take number from line 11, set as variable "triangles"
if (i == 11)
{
getline (inputFile,line);
size_t last_index = line.find_last_not_of("0123456789");
string str = line.substr(last_index);
faces = atoi(str.c_str()); //Convert to int
cout << "faces " + str << endl;
}
if (i == 13)
{
i++;
break;
}
cout << "line: " + i << endl; //Prints line number
i++;
}
} catch(const char* error) {
cout << "Cannot read file, please try again." << error;
}
return 0;
}
This program is simply trying to read file, take a number from a couple of lines and for each line print "line: " with respective line number. It looks like C++ iterates differently to Java?
For some reason this program outputs:
*ine:
ne:
vertices 752
e:
:
Cannot read mesh, please try again.
faces r
annot read mesh, please try again.
nnot read mesh, please try again.*
I have no idea why.
This line:
cout << "line: " + i << endl;
should be:
cout << "line: " << i << endl;
Your + is adding i to the string constant "line: ", which has the effect of knocking one character off the front each time round the loop (and eventually going off the end, leading to undefined behaviour).
You can't add objects to strings in C++ in the way you're attempting, but you can send multiple objects to cout by repeated use of <<.
You then have the same problem here:
cout << "vertices " + str << endl;
and here:
cout << "faces " + str << endl;

File pointer movement for getline

I have got an input file with following data
2
100
2
10 90
150
3
70 10 80
Now, I am able to read till 4th line ( 10 90) but when reading 5th line(150), the file pointer seems to be stuck at 4th line. I have tried infile.clear() just incase. How do I make sure that file pointer is moving correctly or position it at next line? Appreciate your feedback.
-Amit
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
int main(void) {
int cases;
int total_credit=0;
int list_size=0;
string list_price;
//Read file "filename".
ifstream infile;
infile.open("A-large-practice.in",ifstream::in);
if(!infile.is_open()) {
cout << "\n The file cannot be opened" << endl;
return 1;
}
else {
cout<<"Reading from the file"<<endl;
infile >> cases;
cout << "Total Cases = " << cases << endl;
int j=0;
while (infile.good() && j < cases) {
total_credit=0;
list_size=0;
infile >> total_credit;
infile >> list_size;
cout << "Total Credit = " << total_credit << endl;
cout << "List Size = " << list_size << endl;
//cout << "Sum of total_credit and list_size" << sum_test << endl;
int array[list_size];
int i =0;
while(i < list_size) {
istringstream stream1;
string s;
getline(infile,s,' ');
stream1.str(s);
stream1 >> array[i];
//cout << "Here's what in file = " << s <<endl;
//array[i]=s;
i++;
}
cout << "List Price = " << array[0] << " Next = " << array[1] << endl;
int sum = array[0] + array[1];
cout << "Sum Total = " << sum << endl;
cout <<"Testing" << endl;
j++;
}
}
return 0;
}
The problem is that you're using ' ' (space) as your "line terminator" for getline. So when you're reading the numbers on line 4 into the string s, the first one will be "10" and the second will be "90\n150\n3\n70" -- that is, everything up to the next space. This is almost certinaly not what you want and is leading to your confusion about where you are in the file. The next number you read will be 10, leading you to think you're on line 4 when in fact you're on line 7.
edit
The easiest way to fix this is probably to not use getline at all and just read ints directly from the input:
while (i < list_size)
infile >> array[i++];
This ignores the newlines altogether, so the input might as well be all on one line or split between lines randomly, but as you have an initial number that tells you how many numbers to read, that's just fine.