Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Firstly be mercyful, i'm a beginner in C++.
I wrote this code for my interpreter: Reading a line from source and splitting line to words. I using a vector object for storing words. Here is the code, Source is file descriptor (ifstream):
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
typedef unsigned int UIntegerP;
#define V(X, Y, Z) X##Y##Z
#define Version V(0, 0, 1)
#define Free 0x0
int main(int ACount, char *Arguments[]){
if(ACount < 2){
cout << "Venus Interpreter - Engine V: " << Version << " - Interprate: -I <Source> \n";
}else{
if(Arguments[1][0] == '-' && Arguments[1][1] == 'I'){
if(ACount < 3){
cout << "Error: No input files \n";
}else if(ACount > 3){
cout << "Error: Too much arguments \n";
}else{
ifstream Source(Arguments[2]);
if(Source.good()){
# define __TEST__ 1
string Line;
vector<string> Words;
string Word;
while(getline(Source, Line)){
for(unsigned long Index = 0; Index <= Line.length(); Index++){
if(Line[Index] == ' ' or Line[Index] == '\0'){
Words.push_back(Word); //Inject the Word to Words
Word.clear();
} else {
Word += Line[Index];
}
}
# if __TEST__
cout << Words[0] << "\n";
# endif
//Interpration starts here
Words.clear();
}
}else{
cout << "Error: File does not exist \n";
}
Source.close();
}
}else{
cout << "Error: Unknown operand \n";
}
}
return 0;
}
And this is the file interpreted by program:
10 * 20 / 5 * 10
Asparagas
And this is the output:
10
10
Like you can see here, value is duplicated. What is the problem?
You problem is that for the line 10 * 20 / 5 * 10 you insert the words into your vector, and then print out its first element
#if __TEST__
cout << Words[0] << "\n";
#endif
You then (I assume) think that you are clearing the vector with the following line
Words.empty();
However, this doesn't clear the vector, it returns a boolean showing whether the vector is empty or not (documentation on vector.empty())
To clear your vector you should use vector.clear()
The second time around your loop, when you're processing asparagus, you print the first element in the vector, which is 10, because it's still in the vector from the first getline
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I have been trying to figure this out. I'm very new to C++. I have tried using this: (what modifications would be needed?)
while(!openFile.fail())
{
getline(openFile,myArray[size])
}
My array size is the same as the number of paragraphs. However, I can't figure out how to consider the paragraphs as one element of the array.
Edit [How I did it]:
while(!openFile.fail()) // while no errors keep going.
{
// then i needed a for loop to iterate [size of array] times.
for ( int i = 0; i < sizzArr; i++)
{
getline(tempFile, copyDataF); // this getline gets my first line from the data file into our copyDataF.
while (copyDataF.length() != 0) // when what we copied is not empty
{
arr[i] = arr[i] + copyDataF + "\n";
getline(tempFile, copyDataF); /* assuming next line is blank, our while loop will stop,
the iteration will repeat till end of file (+ depends on the for loop). */
}
}
[ thank you everyone who tried to help as i admit my question wasn't clear enough ]
I'm not entirely sure what step you're having trouble with, but if I understand correctly. You have a file of some kind that you want to read from and a std::string array initialized to have size equaling the number of lines in the file. You can easily open a file with <ifstream> using open() and then read the file line by line with std::getline(), adding each line to the resultant array.
If you want to perform any further logic (searching for spaces in a line, whatever else) this should be enough to get you headed in the right direction. For context, the ./foo.txt file contains 3 newline separated strings of text.
#include <iostream>
#include <ifstream>
using namespace std;
int main() {
ifstream file;
string line;
file.open("./foo.txt", std::ios_base::in);
string lines[3];
int i = 0;
if (file.is_open()) {
// begin reading the file line by line
while (std::getline(file, line)) {
cout << "line: " << line << endl;
lines[i] = line;
i++;
}
} else {
cout << "error opening file" << endl;
}
cout << "printing array" << endl;
for (int j = 0; j < 3; j++) {
cout << lines[j] << endl;
}
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
char arr[10]="\0",arr1[2][5]={'\0'};
cout<<"enter the full line : ";
gets(arr);
for (int i=0;i<1;i++)
{
for (int j=0;j<10;j++)
{
if(j<=4)
{
arr1[0][j]=arr[j] ;
}
else if (j>4)
{
arr1[1][j-5]=arr[j] ;
}
}
}
for(int j=0;j<5;j++)
{
cout<<arr1[0][j]<<" ";
}
cout<<endl;
for(int j=0;j<5;j++)
{
cout<<arr1[1][j]<<" ";
}
Here what i am trying to do is converting a 1d array in to 2d array.
my main purpose is to store 1d array on a 2d and when the first row is completed it should shift the string to next row it is doing all the as i have declared the arr[10] and inputting 10 charcter string through get(arr) it is storing the array as i want but at the end displays an error window i dont know why the program is running perfect as well as giving this error window
my input : hanzlaamja (10charcters)
my output:
h a n z l
a a m j a
according to my wish but the main problem is the error window.
note : there is nothing in error box or warning box.
My program is working perfectly, but i am getting an error of array corruption.
Can anybody help me out? I would be very thankful
please see this error message
full picture
The problem is that you read in 10 characters (e.g. "hanzlaamja") and the string termination character '\0', which is automatically added by gets. Thereby you exceed array bounds, as this would require space for 11 characters. So it would already work if you wrote char arr[11];. But as mentioned in the comments, do not use gets; it is unsafe and it does not prevent you from exceeding array bounds. The following snippet shows how to do this part better:
...
char arr[11]="\0",arr1[2][5]={'\0'};
cout<<"enter the full line : ";
// gets(arr);
if (!fgets(arr,11,stdin)) {
cout << "no value read." << endl;
return 1;
}
...
A lot of your loops could be written shorter / better readable. But that's not the actual topic.
Adding to the great point pointed out by #Stephan Lechner, I have composed a solution "as close as possible" to your original.
Compiled under visual studio 2017.
#include "stdafx.h"
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
cout << "main - start" << endl;
const size_t numOfRows = 2;
const size_t numOfCol = 5;
const size_t numCharsInSingleDimArray = 10;
char arr[numCharsInSingleDimArray] = { '\0' }, arr1[numOfRows][numOfCol] = { '\0' };
cout << "enter the full line : ";
gets_s(arr); // Note:If the buffer (arr) is too small to contain the input line and null terminator, these functions invoke an invalid parameter handle.
cout << "main - entered:" << arr << endl;
char* twoDimArrStartLoc = &(arr1[0][0]); // as user4581301 pointed out, it is also possible to "approach" it by treating the two dimensional array as a contiguous bytes in memory
for (size_t i = 0, j = 0; i< numCharsInSingleDimArray; ++i, ++j)
{
twoDimArrStartLoc[j] = arr[i];
}
cout << "main - after converting the 1d array into 2d array, arr1 is:" << endl;
for (size_t i = 0; i < numOfRows; ++i)
{
for (size_t j = 0; j < numOfCol; ++j)
{
cout << "arr1[" << i << "]" << "[" << j << "]:" << arr1[i][j] << " ";
}
cout << endl;
}
// for debug - you can remove this if not needed...
cout << "main - end, enter any key and press enter to terminate..." << endl;
char tmp;
cin >> tmp;
return 0;
}
Hope it helps.
Cheers,
Guy.
thank you everyone for your support the MAIN mistake i was doing is the use of gets(arr) and doing arr[10] as if you are using function gets(arr) you have to give one extra index which is used by this function gets(arr) i.e. arr[11]
solved :)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I read array from the text file and I want to copy this array's elements to another text file
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
const int ARRAY_SIZE = 5;
int numbers[ ARRAY_SIZE];
int count = 0;
cout << "1. before opening file\n";
ifstream inputFile;
inputFile.open("test.txt");
if (!inputFile)
{
cout << "error opening input file\n";
return 1;
}
cout << "2. after opening file\n";
cout << "3. before reading file, count = " << count << '\n';
while (count < ARRAY_SIZE && inputFile >> numbers [ count])
count++;
inputFile.close();
cout << "4. after reading file, count = " << count << '\n';
cout<< "The numbers are : ";
for (int i = 0; i < count; i++)
cout << numbers[i] << " ";
cout<< endl;
cout << "5. Program ending" << endl;
return 0;
}
I added this code but it doesn't work. How can I copy this array's elements to destination.txt file?
ofstream fstreamFile("destination.txt");
copy(
numbers,
numbers + sizeof(numbers),
ostream_iterator<int>(fstreamFile)
);
my elements are 10,20,30,40 but in the destination.txt file, output is "10203040160641613632767-1973944304-...."
The problem is that you use sizeof for the end "iterator" of the array.
The sizeof operator returns the size in bytes, not in array elements. That means you will go way out of bounds beyond the end of the array.
I suggest you change to use the standard std::begin and std::end helper functions to get the "iterators" for the array:
std::copy(std::begin(numbers), std::end(numbers), ...);
For proper arrays (but not for pointers, and remember that arrays decays to pointers very easily) those functions will do the right thing.
I am studying binary file of C++ nowadays. I made a example code for it, but it does not work well.
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream writeFile;
ifstream readFile;
int temp = 1;
writeFile.open("file.dat", ios::binary);
for (int i = 5; i <= 10 ; i++) // range 5 to 10
writeFile.write((char*)(&i), sizeof(i));
writeFile.close();
readFile.open("file.dat", ios::binary);
readFile.seekg(0);
while (!readFile.eof()) {
readFile.read((char*)(&temp), sizeof(temp));
cout << "temp: " << temp << endl;
readFile >> ws;
}
readFile.close();
system("pause");
return 0;
}
Here is the result:
temp: 5
temp: 6
temp: 7
temp: 8
temp: 167772160
temp: 167772160
When I change the range not to include 9 (for example, 5 to 8), it works well. Also, When I make the same code with double type, it works well. So I think the integer 9 is problem. Can you tell me why?
readFile >> ws; discards white space, which is non-sense for a binary stream. In this case, the character value 9 (which is '\t') is skipped, corrupting your stream. Simply remove that line.
The second problem is you are not checking the state of the stream between reading and displaying the value. EOF is only detected after a read would exceed the end of the file. This is why you get your invalid value twice, the second time the read fails and simply leaves temp with it's previous value. See this question for a more details.
The answer by François Andrieux already has the answer to the question of why your code behaves the way it does.
Here are couple of methods to fix the problem.
Use a for loop to read the numbers. It mirrors the loop used to write to it.
readFile.open("file.dat", ios::binary);
for (int i = 5; i <= 10 ; i++)
{
readFile.read((char*)(&temp), sizeof(temp));
cout << "temp: " << temp << endl;
}
readFile.close();
Use the while loop correctly.
readFile.open("file.dat", ios::binary);
while (readFile.read((char*)(&temp), sizeof(temp)))
{
cout << "temp: " << temp << endl;
}
readFile.close();
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm making a word search game and I've been trying to get a random set of numbers from a preexisting vector that's been shuffled. I can do so, but when I iterate through the vector and print the strings, the number of strings is inconsistent with the value returned by numWords, which supposedly returns the number of items in a vector.
I've been looking at it over and over, but I cannot figure out why it's inconsistent most of the time. Also, I was trying to get a fixed set of 8 words in THE_SET, but the inconsistency pushed me to try a random number of words, but it's still inconsistent. If there's a way I could make THE_SET consistently 8 random words, I'd like to know.
**EDIT: I've got the problem solved, THANKS. [: And I also understand now. I just don't know whether I was confusing debugging with anything or not...since I click "Debug" to check for errors and run my file. Huh. I'm still a beginner and practicing, so I forget some things I've read... And sorry if I misinterpreted anyone.
Everything else seems to be working fine.
// word search.cpp : main project file.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <cctype>
#include <iterator>
using namespace std;
void dispBoard(const vector<string>& wordSet);
void checkGuess(string entry, const vector<string>& wordSet);
int numWords(const vector<string>& wordSet);
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int numLeft = 0;
int main()
{
srand(static_cast<unsigned int>(time(0)));
random_shuffle(alphabet.begin(), alphabet.end());
vector<string> wordSets;
wordSets.push_back("CHICKEN");
wordSets.push_back("BEEF");
wordSets.push_back("DISHONOR");
wordSets.push_back("LAWNMOWER");
wordSets.push_back("LEGEND");
wordSets.push_back("PROGRAMMING");
wordSets.push_back("DEVELOPER");
wordSets.push_back("HOMEWORK");
wordSets.push_back("TERRIBLE");
wordSets.push_back("VACATION");
wordSets.push_back("PYTHON");
wordSets.push_back("RUBY");
wordSets.push_back("POKEMON");
wordSets.push_back("BORDERLANDS");
wordSets.push_back("INFINITE");
wordSets.push_back("SMASH");
wordSets.push_back("BROTHERS");
wordSets.push_back("SNAKES");
wordSets.push_back("HAMSTER");
wordSets.push_back("ELEPHANT");
wordSets.push_back("BUFFALO");
wordSets.push_back("PILLOW");
wordSets.push_back("PASTA");
wordSets.push_back("RAMEN");
random_shuffle(wordSets.begin(), wordSets.end());
vector<string> THE_SET(wordSets.begin(), wordSets.begin() + (rand() % 15 + 1)); //vector of current word set, formed from wordSets
//I'd like this to be fixed at 8 words
int MAX_WORDS = numWords(THE_SET); //reinitialization to number of words in THE_SET--why is it inconsistent with printed words???
numLeft = numWords(THE_SET);
cout << "number of words left: " << numLeft << " and MAX WORDS: " << MAX_WORDS << "\n\n"; //checks num of words
vector<string>::iterator iter;
for(iter = THE_SET.begin(); iter != THE_SET.end(); iter++) //prints words in THE_SET--but number of words counted by hand are usually
{ //inconsistent
cout << *iter << " ";
}
cout << "\n\n";
string entry;
do { //main loop of game
dispBoard(THE_SET);
cout << "You have " << numLeft << " words left to find. \n\n";
cout << "(Enter 'EXIT' if you wish to quit the game.)\n";
cout << "Enter your find in UPPERCASE: ";
cin >> entry;
cout << "\n\n";
if(entry == "EXIT") {
return 0;
}
else {
checkGuess(entry, THE_SET);
}
} while(numLeft != 0);
cout << "Congrats! You found all " << MAX_WORDS << " words!!\n\n";
system("PAUSE");
}
void dispBoard(const vector<string>& wordSet) { //this displays a bunch of random letters around the words in THE_SET
vector<string>::const_iterator iter;
for(iter = wordSet.begin(); iter != wordSet.end(); iter++)
{
cout << alphabet.substr(rand() % 8, (rand() % 32 + 1)) << *iter << alphabet.substr(rand() % 8, (rand() % 32 + 1)) << endl;
}
}
void checkGuess(string entry, const vector<string>& wordSet) {
if(entry == "EXIT")
{
cout << "Quitting game.\n\n";
return;
}
else
{
vector<string>::const_iterator iter;
for(iter = wordSet.begin(); iter != wordSet.end(); iter++) {
if(entry == *iter)
{
cout << "That's right! " << entry << " is in the search!\n\n";
numLeft--;
}
}
}
}
int numWords(const vector<string>& wordSet) //supposed to count number of strings in a given vector, but it's inconsistent. Why??
{
unsigned int i = 0;
vector<string>::const_iterator iter;
for(iter = wordSet.begin(); iter != wordSet.end(); iter++)
{
i++;
}
return i;
}
When you execute these lines:
vector<string> wordSets(24);
wordSets.push_back("CHICKEN");
wordSets has 24 empty items an the item "CHICKEN". I suspect, you didn't mean that. Changing the first line to:
vector<string> wordSets;
should fix the wrong number of items problem.
If you want to reduce the number of times memory is allocated by calls to push_back, you can use:
vector<string> wordSets;
wordSets.reserve(24);
This will make sure that wordSets has sufficient memory to hold upto 24 objects.
To elaborate on R Sahu's answer: Writing
vector<string> wordSets(24);
is equivalent to
vector<string> wordSets;
wordSets.resize(24);
I.e. wordSets is initialized to be a vector with 24 elements that you can access using the operator[]. Adding an element to the vector through push_back increases the size of the vector to 25.
What you probably meant to do was to reserve enough room for 24 strings such that the vector need not resize and reallocate memory for the first 24 additions. You can achieve this as follows:
vector<string> wordSets;
wordSets.reserve(24);
Also take a look at reserve() and resize() on cplusplus.com's reference of std::vector.