• We should now be fully online following an overnight outage. Apologies for any inconvenience, we do not expect there to be any further issues.

Reading first letter of every word in txt file

Page 2 - Seeking answers? Join the AnandTech community: where nearly half-a-million members share solutions and discuss the latest tech.

seemingly random

Diamond Member
Oct 10, 2007
5,277
0
0
What does the following display? Is it useful for your app? How can one tell if the contents of str is valid, ie. - no file read error or eof?

string str;
Original_Doc >> str;
cout << str;

Is this a homework assignment? I can't write the whole thing for you.

You need something like this:

for ( ;; )
{
string s;
file >> s;
if eof break;
process(s);
}
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
Oh I don't want the whole thing written, not even part. This part is HW, the first part (With the functions) is a game I am writing.

Well, the getline works just fine for getting the information from the file and storing it as a string (In this case TXT_File).

Then I have the for loop running until i reaches the size of the sentence. I have the find function, finding the index of the first whitespace. Right now I am merely running into a problem trying to find the next white space in the series of words. Thats what I was trying to accomplish with the for loop, but I can't get it to move the cursor along.

-Kevin

 

seemingly random

Diamond Member
Oct 10, 2007
5,277
0
0
I'm not deeply familiar with the c++ standard library. It is quite extensive though - there might be something that tokenizes based on whitespace like other posters have mentioned. If this can't be found you'll have to do it on your own like I did a few posts up or with a combination of standard library string functions.

If not familiar with the term whitespace - it usually include tabs, spaces and newlines (depending on os, lf or cr/lf or cr).
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
Well what I have been working on is finding the white space and then after grabbing the first letter of that word, I delete the white space before executing the find again. Therefore it finds the next whitespace. I'm just getting hung up mentally trying to comprehend how to find the next word before the next whitespace.

-Kevin
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
I get the gist of what you are doing on the lines, but I would really have to do it to manipulate the code in the right way. I originally tried to just use a getline from the file and store it as a string and then have it use that; however, it wants it as a char array. Unfortunately I couldn't figure out how to turn the string into a char array.

-Kevin
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
Hey I got something working here--- I am just running into a runtime error:

#include <fstream>
#include <string>
#include <iostream>
using namespace std;

int main()
{
string filename, Output_File, TXT_File;
size_t i=0, Location, temp=0;
string X;

// Opens and reads the file which the user specifies
ifstream Original_Doc;
cout << "Please enter the file name\n";
cin >> filename;
Original_Doc.open(filename.c_str());

// If file cannot be found returns an error and exits
if (!Original_Doc)
{
cout << "Unable to open file Original_Doc";
exit (1);
}

getline(Original_Doc, TXT_File);

size_t MAX = TXT_File.size();

for (i=0; i<=MAX; i++)
{
if(i!=0)
temp = Location;
Location = TXT_File.find(' ');

X = TXT_File.substr(temp, Location);
X = X.substr(0,1);
TXT_File = TXT_File.erase(Location);

cout << X << endl;
}

return 0;
}

I run it an an error pops up and says the application requested to end in an unexpected way. I don't quite understand why because everything seems sound when i trace through the loop by hand.

-Kevin
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
Originally posted by: Common Courtesy
Remember that indexing starts at 0

Therefore testing against MAX_FILE_SIZE using <= will exceed allocated memory
for (i=0; i<=MAX; i++)

Change the test to <
for (i=0; i<MAX; i++)

I tried. It gives me the error after returning the first capital letter. Right when it is about to go into the loop again it gives me the error and exits.
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
I GOT IT!!!!!!! HAHAHAHAHAHAH!

I have 2 questions still though :)

First off it is running for the size of the original string. So I get the initial letters and then it repeats the last one until it reaches the initial size and ends the for loop, then i get a bunch of these weird characters after it runs out of the last letter.

-Kevin

Edit: Now I have it running for the correct amount of letters!! :) :)

The only thing I cannot figure out is how to make the string small enough so that it doesn't fill it with this one weird character after my loops is done filling it. Can someone tell me how to tell it to stop doing that?
 

seemingly random

Diamond Member
Oct 10, 2007
5,277
0
0
I'll answer your first question with a question. Write a little test program that includes:

ifstream f;
f.open("xxx");
if (! f) error out...
for ( ;; )
{
string s;
f >> s;
if (! f) break; //out of infinite for ( ;; ) loop
cout << '\"' << s << "\"\n";
}

What is the output?

For the next part, check out the string += operator. See where this could be useful? An array (at least not explicit) is not needed.
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
Originally posted by: seemingly random
I'll answer your first question with a question. Write a little test program that includes:

ifstream f;
f.open("xxx");
if (! f) error out...
for ( ;; )
{
string s;
f >> s;
if (! f) break; //out of infinite for ( ;; ) loop
cout << '\"' << s << "\"\n";
}

What is the output?

For the next part, check out the string += operator. See where this could be useful? An array (at least not explicit) is not needed.

I know an array isn't needed. However, because this is a HW problem they want us to do ridiculously senseless things. So if I don't use a char array i don't get a good grade.

I got everything to the right size, but the array is too big for what it contains. Instead of filling it with whitespace, it fills it with this weird character. I think it may be a bug, because even if I modify the array to the exact size, I still get this weird character.

-Kevin
 

seemingly random

Diamond Member
Oct 10, 2007
5,277
0
0
Ok. I agree you should do things as specified in the HW problem and should have asked what it is a while back.

I don't see an array in your posts though. An array definition look like this:

char char_array[10];
int int_array[3];

Maybe you're using array in different context.
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
Oh yea here is the updated code:

#include <fstream>
#include <string>
#include <iostream>
using namespace std;

int main()
{
// Declare and initialize the variables
string filename, Output_File, TXT_File, X, Original;
size_t i=0, Location, F_Array = 1;
char Array[50];

// Opens and reads the file which the user specifies
ifstream Original_Doc;
cout << "Please enter the file name\n";
cin >> filename;
Original_Doc.open(filename.c_str());

// If file cannot be found returns an error and exits
if (!Original_Doc)
{
cout << "Unable to open file Original_Doc";
exit (1);
}

// Reads the line in the file and saves it as TXT_File of type string.
getline(Original_Doc, TXT_File);
// Creates a copy of the original text before the program edits the text of the string.
Original = TXT_File;

// Moves the index through the array until when searching for a white space it returns a -1 for the position
for (i=0; F_Array != -1; i++)
{
Location = TXT_File.find(' ');
// Saves the text between cursor 0 and the white space as X.
X = TXT_File.substr(0, Location);
// Takes the first letter of the word saved as X.
X = X.substr(0,1);
// Erases the text before the white space so the next white space can be found in the string.
TXT_File = TXT_File.erase(0, Location+1);

// Creates a pointer called psz that points to the X string. This pointer allows the char array to be filled despite
// the fact that X is a string.
char* psz = _strdup(X.c_str());
Array[(This is triggering italics)I] = * psz;
F_Array = TXT_File.find(' ');

// When the program cannot find anymore whitespace, this means there is only one word left. This grabs the first
// character of that word and stores it in the respective cell in the array and then erases the rest of the string.
if (F_Array == -1)
{
i++;
Location = TXT_File.find_last_of(' ');
X = TXT_File.substr(0, Location);
X = X.substr(0,1);
TXT_File = TXT_File.erase(0, Location+1);
char* psz = _strdup(X.c_str());
Array[(This is causing italicsI] = * psz;
}
}

// Outputs the values in the array along with the original string for comparison.
cout << Array << endl << ": " << Original << endl;

// Closes the program.
return 0;
}
 

seemingly random

Diamond Member
Oct 10, 2007
5,277
0
0
I don't understand about the array being too big. One the banes of programmers is memory allocation. How would you know how big Array should be before you parse the line from the file? As it is now, depending on the file, Array could be overflowed but this might not be important for this assignment.

The definition of character string (not standard library string) is a series of non-null characters terminated by a null character.

Nice job with the comments. It would be useful if the problem requirements were documented at the top of the file in a few lines.

After this is handed in, post back and I'll post what I came up with.
 

Daverino

Platinum Member
Mar 15, 2007
2,004
1
0
I understand this is totally unhelpful but:

while (<STDIN>) {
print (join ("\n", map (substr (0,1), split (/ /))));
}

Didn't test it, but golf anyone?
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
Originally posted by: seemingly random
I don't understand about the array being too big. One the banes of programmers is memory allocation. How would you know how big Array should be before you parse the line from the file? As it is now, depending on the file, Array could be overflowed but this might not be important for this assignment.

The definition of character string (not standard library string) is a series of non-null characters terminated by a null character.

Nice job with the comments. It would be useful if the problem requirements were documented at the top of the file in a few lines.

After this is handed in, post back and I'll post what I came up with.

It has been handed in today at lab. He said I am going to get points off because of how i found the initial letter. I didn't show it but i was absolutely pissed. They wanted to use the string class and substr and I DID, yet because I didn't do it their way I will, apparently, get points off.

-Kevin
 

seemingly random

Diamond Member
Oct 10, 2007
5,277
0
0
Hey, you put a lot of effort into it. You learned a few things about programming and also a few things about the peculiarities of your teacher. Just substitute customer for teacher and you've got a picture of later down the road. I learned a little by helping so I should thank you...

Here's what I came up with - don't know if it would have met the requirements though:

...

int main(int argc, char** argv)
{
if (argc < 2) { cout << "usage: cmd filename" << endl; return 2; }

ifstream file;

file.open(argv[1]);
if (! file) { cout << "can't access: " << argv[1] << endl; return 2; }

string letters;
for ( ;; )
{
string data;
file >> data;
if (! file) break;
// cout << "data:\"" << data << "\"\n";
letters += data[0];
}

cout << "letters: \"" << letters << "\"\n";

file.close();

return 0;
}

There are several convenient things about this:
- file >> data; turns out to be the exact tokenizer you were looking for. It also handles files with multiple lines.
- string letters; uses the string class to manage memory for you.

A 'real' program would require more error checking.
This wouldn't handle the case where a separate grouping of letters is output for each line of the file.
 

Gamingphreek

Lifer
Mar 31, 2003
11,679
0
81
I actually think that is (generally) what they were looking for I think.

It was really vague in the problem. So if I get less than a 90 (A-) I am going to the TA and asking what in the world they are thinking.

Thank you so so much for all the help. I did indeed learn quite a bit about the string class and working in between it and others.

-Kevin