String subscript out of range error "C++" - c++

This program takes a text file and changes each word into pig Latin. I have gotten everything to work but continue to get the error "subscript out of range". I have tried to change many things but cant get it to go away. Can someone explain why I am getting this error?
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
void piglatin ( string word[], string temp, ifstream & in, int num);
int main()
{
string word[300];
string original[300];
string temp;
ifstream in;
int i=0,
j=0,
x=0,
par=0,
length=0;
in.open("text.txt");
if (in.is_open()) { //Checks if file is open
cout << "\nFile is open....\n\n\n";
} else {
cout << "Error: Failed to open!\n";
cout << "Exiting program\n";
exit(-1);
}
cout<<"Original text\n\n";
do {//Continues while loop until no more input.
in >> original[x];
cout << original[x] << " ";
x++;
par = par + x;
} while (!in.eof());
cout<<"\n\n";
cout<<"Pig Latin\n\n";
piglatin(original,temp,in,par);
return 0;
}
void piglatin ( string word[], string temp, ifstream & in, int num)
{
int i=0, length, j=0,a=0;
for(j = 0; j < num; j++) {
string str (word[j]);
length = str.size();
temp[0] = word[j][0];
if ((temp[0] == 'a') ||
(temp[0] == 'e') ||
(temp[0] == 'i') ||
(temp[0] == 'o') ||
(temp[0] == 'u'))
{
word[j] += "way";
} else {
for(i = 0; i <= length-1; i++) {
word[j][i] = word[j][i+1];
}
word[j][length-1] = temp[0];
word[j] += "ay";
}
cout << word[j] << " ";
length = 0;
}
cout << "\n\n";
}

This statement
temp[0] = word[j][0];
is invalid because string temp is empty and you may not use the subscript operator with empty strings to store a character.
You could write before the for loop for example
temp.resize( 1 );
Also I do not see any sense in the parameter temp. Instead of string temp you could use in the function local variable char temp; because you are using temp only to store one character.

I believe you are missing a parameter to the ifstream: The ifstream object requires two parameters, a filename and a mode which describes the requested i/o mode for the file.
in.open("text.txt");
Should be:
in.open("text.txt", ifstream::in);
Here is a link to the API for ifstream.open:
http://www.cplusplus.com/reference/fstream/ifstream/open/

Related

Program not exiting for loop after returning?

This program is suppose to identify tokens from an input file. Here is some of the input file
Test = Exam
The program should read in a line of text and identify the separate "phrases" that appear. For example the first line would produce the output "Test" -> IDENTIFIER, "=" -> ASSIGNMENT OPERATOR, "Exam" -> IDENTIFIER. Each line is a separate input to be read. I have a for loop to check the characters in the string to see what type of identifier it might be. For some reason, my program will not exit the for loop in my token type function. I have tried debugging but I am extremely confused where the program is getting stuck. I threw some cout statements in the program to maybe help identify the issue. For some reason the input is not getting past the first word "Test". It will read it in 3-5 times and then just error out.
Here is the current output (The program wouldn't normally output each individual character and index #, I just included it to make it possibly easier to follow along and locate the error)
File Opened
Test = Exam
0 T e s t
1 T e s t
2 T e s t
3 T e s t
4
5
6
7 T e s t
E x a m
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
using namespace std;
const int SIZE = 100;
enum Token { IDENTIFIER, ARITHMETIC, RELATIONAL, LOGICAL, COMPOUND,
ASSIGNMENT, INTEGER, ILLEGAL, ENDLINE };
void getData(ifstream& inData, char data[]);
Token getTokenType(char data[], Token type[], char subStr[][SIZE], int index);
void displayData(char data[], Token type[], char subStr[][SIZE]);
void displayType(Token type[], int index);
int main()
{
char input[SIZE], subString[SIZE][SIZE];
Token type[SIZE];
ifstream inFile;
ofstream outFile;
inFile.open("mp5in.txt");
if (inFile)
cout << "File Opened" << endl << endl;
else
cout << "File Failed to Open" << endl << endl;
getData(inFile, input);
while (inFile)
{
for (int i = 0; type[i] != ENDLINE; i++)
{
cout << i << " ";
type[i] = getTokenType(input, type, subString, i);
cout << endl;
}
displayData(input, type, subString);
getData(inFile, input);
}
inFile.close();
return 0;
}
void getData(ifstream& inData, char data[])
{
int i = 0;
while (inData && data[i] != '\n')
{
inData.get(data[i]);
cout << data[i];
if (data[i] == '\n')
break;
i++;
}
}
Token getTokenType(char data[], Token type[], char subStr[][SIZE], int index)
{
int size = index;
int row = index, col = index;
bool valid = true, end = false;
for (int i = index; data[i] != '\n'; i += size)
{
if (isalpha(data[col]))
{
for (col = 0; subStr[row][col] != ' '; col++)
{
subStr[row][col] = data[col];
cout << subStr[row][col] << " ";
if ((!isalpha(subStr[row][col]) || !isdigit(subStr[row][col])) &&
subStr[row][col] != '_')
valid = false;
if (subStr[row][col] == ' ' && !valid)
return ILLEGAL;
else if (subStr [row][col] == ' ' && valid)
return IDENTIFIER;
}
}
}
}
Not all the program is here. I left it out as the program does not currently get that far along in the program.

find a certain word in sentence in c++

I want to write a program that finds a word that the user entered I think my solution is right but when I Run it, the program shows nothing in the console
anybody can fix it?
int main()
{
char sen[200],del[200],maybedel[200];
cout<<"enter sentence :"<<endl;
cin.getline(sen,200);
cout<<"which word do you want to delete ?";
cin.getline(del,200);
int len = strlen(sen);
for(int i=0;i<=len;i++)
{
if(sen[i]==' ')
{
for(int j=i;j<=len;j++)
if(sen[j]==' ' || sen[j]=='\0')
for(int k=i+1,t=0;k<j;k++,t++)
maybedel[t]=sen[k];
if(maybedel==del)
cout<<maybedel;
}
}
return 0;
}
The line if(sen[i]==' '), line 12 of your code , prevents code from entering the block unless the sentence begins with (' ')!
I changed the code a bit and now it works fine.
char sen[200], del[200], maybedel[200];
cout << "enter sentence :" << endl;
cin.getline(sen, 200);
cout << "which word do you want to delete ?" << endl;
cin.getline(del, 200);
int len = strlen(sen);
int t = 0;
for(int i = 0; i <= len; i++) {
if(sen[i] == ' ' || sen[i] == '\0') {
maybedel[t] = '\0';
t = 0;
if(strcmp(del,maybedel)==0) {
cout << maybedel << endl;
}
}
else
{
maybedel[t] = sen[i];
t++;
}
}
The major reason for no output is
if (maybedel == del) // <<< this will *never* be true
cout << maybedel; // will never run
Since comparing "strings" in arrays needs help from std::strcmp(maybedel,del) == 0 would be better.
UPDATE:
Another attack method is to avoid raw loops and utilize the STL to your favor. Here's a more robust solution:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <vector>
using namespace std;
int main() {
cout << "enter sentence :\n";
string sen;
if (!getline(cin, sen)) throw std::runtime_error("Unable to read sentence");
cout << "which word do you want to delete ? ";
string del;
if (!(cin >> del)) throw std::runtime_error("Unable to read delete word");
istringstream stream_sen(sen);
vector<string> arrayofkeptwords;
remove_copy_if(istream_iterator<string>(stream_sen), istream_iterator<string>(),
back_inserter(arrayofkeptwords),
[&del](auto const &maybedel) { return maybedel == del; });
copy(begin(arrayofkeptwords), end(arrayofkeptwords),
ostream_iterator<string>(cout, " "));
cout << '\n';
}

print 2nd word in a string with its size in C++

I am trying to make a program in which a user enters a string and i will print out the second word in the string with its size.
The delimiter's are space( ), comma(,) and tab( ).
I have used a character array and fgets to read from user and a character pointer that points to the first element of the array.
source code:
#include"iostream"
#include<stdio.h>
#include<string>
using namespace std;
// extract the 2nd word from a string and print it with its size(the number of characters in 2nd word)
int main()
{
char arr[30], arr1[30];
char *str = &arr1[0];
cout<<"Enter a string: ";
fgets(str, 30, stdin);
int i = 0, j, count = 1, p = 0; // count is used to find the second word
// j points to the next index where the first delimiter is found.
// p is used to store the second word found in character array 'arr'
while(*(str+i) != '\n')
{
if(*(str+i) == ' ' || *(str+i) == ',' || *(str+i) == ' ')
{
count++;
if(count == 2)
{
// stroing 2nd word in arr character array
j = i+1;
while(*(str+j) != ' ' || *(str+j) != ',' || *(str+j) != ' ')
{
arr[p] = *(str+j);
cout<<arr[p];
p++;
i++;
j++;
}
break;
}
}
i++;
}
arr[p+1] = '\0'; // insert NULL at end
i = 0;
while(arr[i] != '\0')
{
cout<<arr[i];
i++;
}
cout<<"("<<i<<")"<<endl;
return 0;
}
Help me out with this.
To start, don't use std::cin for testing. Just set a value in your code for consistency and ease of development. Use this page for a reference.
#include <iostream>
#include <string>
int main() {
std::string str("this and_that are the tests");
auto start = str.find_first_of(" ,\n", 0);
auto end = str.find_first_of(" ,\n", start + 1);
std::cout << str.substr(start, end - start);
return 0;
}
And this is still somewhat of a hack, it just depends where you are going. For instance the Boost library is rich with extended string manipulation. If you are going to parse out more than just one word it can still be done with string manipulations, but ad-hoc parsers can get out of hand. There are other tools like Boost Spirit to keep code under control.
The delimiters used when extracting from a stream depends on the locale currently in effect. One (cumbersome) way to change the extraction behaviour is to create a new locale with a special facet in which you specify your own delimiters. In the below example the new locale is used to imbue a std::stringstream instead of std::cin directly. The facet creation part is mostly copy/paste from other answers here on SO, so you'll find plenty of other examples.
#include <iostream>
#include <locale> // std::locale, std::ctype<char>
// https://en.cppreference.com/w/cpp/locale/ctype_char
#include <sstream> // std::stringstream
#include <algorithm> // std::copy_n
#include <vector> // a container to store stuff in
// facet to create our own delimiters
class my_facet : public std::ctype<char> {
mask my_table[table_size];
public:
my_facet(size_t refs = 0)
: std::ctype<char>(&my_table[0], false, refs)
{
// copy the "C" locales table to my_table
std::copy_n(classic_table(), table_size, my_table);
// and create our delimiter specification
my_table[' '] = (mask)space;
my_table['\t'] = (mask)space;
my_table[','] = (mask)space;
}
};
int main() {
std::stringstream ss;
// create a locale with our special facet
std::locale loc(std::locale(), new my_facet);
// imbue the new locale on the stringstream
ss.imbue(loc);
while(true) {
std::string line;
std::cout << "Enter sentence: ";
if(std::getline(std::cin, line)) {
ss.clear(); // clear the string stream from prior errors etc.
ss.str(line); // assign the line to the string stream
std::vector<std::string> words; // std::string container to store all words in
std::string word; // for extracting one word
while(ss>>word) { // extract one word at a time using the special facet
std::cout << " \"" << word << "\" is " << word.size() << " chars\n";
// put the word in our container
words.emplace_back(std::move(word));
}
if(words.size()>=2) {
std::cout << "The second word, \"" << words[1] << "\", is " << words[1].size() << " chars\n";
} else {
std::cout << "did not get 2 words or more...\n";
}
} else break;
}
}
#include"iostream"
#include<stdio.h>
#include<string>
#include <ctype.h>
using namespace std;
int main()
{
char c;
string str;
char emp = ' ';
cout<<"Enter a string: ";
getline (cin,str);
int j = 0, count = 1, counter = 0;
for (int i = 0; i < str.length() && count != 2; i++)
{
cout<< str[i] <<endl;
if( isspace(str[i]) || str[i] == ',' || str[i] == '\t' )
{
count++;
if(count == 2)
{
j = i+1;
while(j < str.length())
{
if (isspace(str[j]) || str[j] == ',' || str[j] == '\t')
{
break;
}
cout<<str[j];
counter++;
j++;
}
cout<<endl;
}
}
}
cout<<"size of the word: "<<counter<<endl;
return 0;
}
This is a simple answer to what you want, hope to help you.
// Paul Adrian P. Delos Santos - BS Electronics Engineering
// Exercise on Strings
#include <iostream>
#include <sstream>
using namespace std;
int main(){
// Opening Message
cout << "This program will display the second word and its length.\n\n";
// Ask for a string to the user.
string input;
cout << "Now, please enter a phrase or sentence: ";
getline(cin, input);
// Count the number of words to be used in making a string array.
int count = 0;
int i;
for (i=0; input[i] != '\0'; i++){
if (input[i] == ' ')
count++;
}
int finalCount = count + 1;
// Store each word in a string array.
string arr[finalCount];
int j = 0;
stringstream ssin(input);
while (ssin.good() && j < finalCount){
ssin >> arr[j];
j++;
}
// Display the second word and its length.
string secondWord = arr[1];
cout << "\nResult: " << arr[1] << " (" << secondWord.size() << ")";
return 0;
}

Parsing out things surrounded by quotes in C++

I'm trying to make a parser that would only take text surrounded by quotes and place it in a new file I've already tried many times but can't figure it out it would have to take the original text out of a file by the way then place it in a new file I would like to do this in C++.
This is what I currently have:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char current_letter;
char quote_mark = '"';
int isquote = 0;
std::cin >> current_letter;
LOOP : do
{
if(current_letter == quote_mark) {++isquote;}
if(isquote == 1 && current_letter != quote_mark) {std::cout << current_letter;}
if(isquote == 1 && current_letter == quote_mark) {--isquote;}
if(isquote == 0) {goto LOOP;}
} while (cin >> current_letter);
if(cin != current_letter) {cout << "END" <<endl;}
return(0);
It doesn't print anything now but it used to print out random stuff or just quote marks.
You could just do something like this:
string str;
getline(cin, str);
string currStr = "";
for (int i = 0; i < str.length(); i++)
{
if (str[i] != '\"') currStr += str[i];
}
cout << currStr << "\n";
This won't work if there are double quotes within the text that you want to parse however.

Why doesn't this code run?

Hey, sorry if this is asked a lot but I have no idea what the problem here is.
In the C++ code below, I'm reading from a user defined input file and generating output. I've been writing it piece by piece and putting it together, compiling, testing, etc as I go to work out the bugs. This is a learning experience for me, first self-directed program I guess...
Anyways, when I run the code, the command prompt prints ONE line and goes unresponsive. I would say it has been caught in some kind of loop, but I believe that's impossible.
I think it might have something to do with the array I'm trying to declare, I wanted to make a dynamic string array but I found out that's difficult...
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cctype>
#include <string>
using namespace std;
int wordCount(string line)
{
int fpos, fpos2;
int count = 0;
fpos = line.find_first_not_of(' ');
line.erase(0, fpos);
while(line.size() > 0)
{
fpos = line.find_first_of(' ');
if(line.at(0) == '"')
{
line.erase(0, 1);
for(int i = 0; i <line.size(); i++)
if(line.at(i) == '"' && line.at(i-1) != '\\')
{
fpos2 = i;
break;
}
line.erase(0, fpos2 + 2);
}
else
line.erase(0, fpos + 1);
count++;
}
return count;
}
int main()
{
//Current line; Input file; Output file;
string currentline, fileName, outFileName;
ifstream fin;
ofstream fout;
cout << "Enter input file name: ";
getline(cin, fileName);
cout << "Enter output file name: ";
getline(cin, outFileName);
fin.open(fileName.c_str());
if (!fin.good()) throw "I/O error";
fout.open(outFileName.c_str());
if (!fout.good()) throw "I/O error";
getline(fin, currentline);
while (!currentline.empty())
{
int pos, pos1;
pos = currentline.find("//");
string postScript = currentline.substr(pos+2,-1);
pos = currentline.find_first_of(';');
string xline = currentline.substr(0,pos+1);
cout << xline << endl;
int size = wordCount(xline);
string *words;
words = (string *) malloc (size*sizeof(string));
words = new string[size];
pos = xline.find_first_not_of(' ');
xline.erase(0, pos);
for ( int i = 0; i < size; i++ )
{
pos = xline.find_first_of(' ');
if ( xline.at(0) == '"' )
{
xline.erase(0, 1);
for(int a = 0; a < xline.size(); a++) //This for loop finds the end of a quoted statement within the line.
if ( xline.at(a) == '"' && xline.at(a-1) != '\\' )
{
pos = a;
break;
}
words[i] = xline.substr(0,pos);
xline.erase(0,pos + 2);
}
else
{
words[i] = xline.substr(0,pos);
xline.erase(0,pos + 1);
}
cout << words[i] << endl;
}
cout << xline << endl << endl;
getline(fin, currentline);
}
return 0;
}
I would suggest you commenting out bits of code until it starts to work the way you expect (Usually the problematic bit will become obvious this way.) Once you figure out what is wrong you can ask a more specific question on StackOverflow.
You should use a debugger to investigate the program behavior.
To avoid single stepping the whole program, you can set breakpoints where you expect to passs the sequence. When a breakpoint is not hit you can use single stepping from the previous point. Additionally you can look at variables content.
It never finds the end quote:
if ( xline.at(a) == '"' && xline.at(a-1) != '\\' )
{
pos = a;
break;
}
Try this instead:
if (xline.at(a) == '"')
{
pos = a;
break;
}
You only need to escape " if its contained in a string literal, e.g. "There's a \" in this literal"