0

So in this program I'm trying to go through word by word and make it only lowercase letters, no whitespace or anything else. However, my string "temp" isn't holding anything in it. Is it because of the way I'm trying to modify it? Maybe I should try using a char * instead? Sorry if this is a stupid question, I'm brand new to c++, but I've been trying to debug it for hours and can't find much searching for this.

#include <string>
#include <iostream>
#include <fstream>
#include <ctype.h>

using namespace std;

int main(int argc, char* argv[]) {

/*if (argc != 3) {
    cout << "Error: wrong number of arguments." << endl;
}*/

ifstream infile(argv[1]);
//infile.open(argv[1]);

string content((std::istreambuf_iterator<char>(infile)),
    (std::istreambuf_iterator<char>()));

string final;
string temp;
string distinct[5000];
int distinctnum[5000] = { 0 };
int numdist = 0;
int wordcount = 0;
int i = 0;
int j = 0;
int k = 0;
int isdistinct = 0;
int len = content.length();
//cout << "test 1" << endl;
cout << "length of string: " << len << endl;
cout << "content entered: " << content << endl;
while (i < len) {
    temp.clear();
    //cout << "test 2" << endl;
    if (isalpha(content[i])) {
        //cout << "test 3" << endl;
        if (isupper(content[i])) {
            //cout << "test 4" << endl;
            temp[j] = tolower(content[i]);
            ++j;
        }
        else {
            //cout << "test 5" << endl;
            temp[j] = content[i];
            ++j;
        }
    }
    else {
        cout << temp << endl;
        //cout << "test 6" << endl;
        ++wordcount;
        final = final + temp;
        j = 0;
        for (k = 0;k < numdist;k++) {
            //cout << "test 7" << endl;
            if (distinct[k] == temp) {
                ++distinctnum[k];
                isdistinct = 1;
                break;
            }
        }
        if (isdistinct == 0) {
            //cout << "test 8" << endl;
            distinct[numdist] = temp;
            ++numdist;
        }
    }
    //cout << temp << endl;
    ++i;
}

cout << wordcount+1 << " words total." << endl << numdist << " distinct words." << endl;
cout << "New output: " << final << endl;

return 0;
}

1 Answers1

1

You can't add to a string with operator[]. You can only modify what's already there. Since temp is created empty and routinely cleared, using [] is undefined. The string length is zero, so any indexing is out of bounds. There may be nothing there at all. Even if the program manages to survive this abuse, the string length is likely to still be zero, and operations on the string will result in nothing happening.

In keeping with what OP currently has, I see two easy options:

Treat the string the same way you would a std::vector and push_back

temp.push_back(tolower(content[i]));

or

Build up a std::stringstream

stream << tolower(content[i])

and convert the result into a string when finished

string temp = stream.str();

Either approach eliminates the need for a j counter as strings know how long they are.

However, OP can pull and endrun around this whole problem and use std::transform

std::transform(content.begin(), content.end(), content.begin(), ::tolower);

to convert the whole string in one shot and then concentrate on splitting the lower case string with substring. The colons in front of ::tolower are there to prevent confusion with other tolowers since proper namespacing of the standard library has been switched off with using namespace std;

Off topic, it looks like OP is performing a frequency count on words. Look into std::map<string, int> distinct;. You can reduce the gathering and comparison testing to

distinct[temp]++;
Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54