still having issue with infile.eof() function

Hi Everyone!

I have to write a small program that reads a file, remove the old (|)delimiter and replace them by a new one ( ,) so I can convert the file into .CSV OR XLSX file. then enclose any pre-existing field of the text that are surrounded by double quotes inside another pair of double quotes;
I wrote the following code to do the job, for some reason it reads only the first line of the text.
can somebody help me?
--------------------------------------------------------------------------
void ProcessData(){
system("CLS");
FileConverter PipeToCommas;
string newline;
string input_sz;
string output_sz;
string the_string;

// while(getline(_file, input_sz)){
getline(infile, input_sz);
int result = 0;
int length = input_sz.length();
while( result != string::npos ){
if(result < length){
result = input_sz.find(",",result);
if(result != -1){
the_string = input_sz.erase(result, 1);
the_string = input_sz.insert(result, "*");
}
}
}
int vert = 0;
while( vert != string::npos ){
if(vert < length){
vert = input_sz.find("|",result);
if(vert != -1){
the_string = input_sz.erase(vert, 1);
the_string = input_sz.insert(vert, "\",\"");
}
}
}
for(unsigned int i = 0; i<the_string.length();++i){
if(the_string[i]=='*'){
the_string[i]=',';
}
}
cout<<the_string<<endl;
}
You only call getline() once, so you're only going to read a single line of text. You're either going to have to enclose everything in a while loop or call ProcessData() in a while loop.
The code is very hard to read, here it is reformatted for legibility (but no other changes):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
void ProcessData()
{
    system("CLS");
    FileConverter PipeToCommas;
    string newline;
    string input_sz;
    string output_sz;
    string the_string;

    // while(getline(_file, input_sz)){
    
    getline(infile, input_sz);
    
    int result = 0;
    int length = input_sz.length();
    
    while ( result != string::npos )
    {
        if (result < length)
        {
            result = input_sz.find(",",result);
            if (result != -1)
            {
                the_string = input_sz.erase(result, 1);
                the_string = input_sz.insert(result, "*");
            }
        }
    }
    
    int vert = 0;
    
    while ( vert != string::npos )
    {
        if (vert < length)
        {
            vert = input_sz.find("|",result);
            if (vert != -1)
            {
                the_string = input_sz.erase(vert, 1);
                the_string = input_sz.insert(vert, "\",\"");
            }
        }
    }
    
    for (unsigned int i = 0; i<the_string.length();++i)
    {
        if (the_string[i]=='*')
        {
            the_string[i]=',';
        }
    }
    
    cout<<the_string<<endl;
} 
Last edited on
Your code is scattered, like you've been given 'help' a couple of times already but are unsure how to make it all work together.

Is this for school?

Or for your job?


Answer truthfully, and you'll get the most useful help I can give for your situation (i.e. the help that will best get you good grades from whomever you report to).
yeah! it's for a School project.
I tried the while(!infile.eof()) it is not outputting anything. that's why I have commented it out.
any help will be greatly appreciated.

Thanks in advance.
Just a couple of other preliminaries...

What's the FileConverter object? Is that part of the assignment or is that the remnant of someone's suggestion?

C++ can basically do this for you very easily, but if you want to do it line by line (like your code tries), then don't loop on EOF. Your code should read lines like this:

1
2
3
4
5
6
string s;
while (getline( infile, s ))
{
  // do something to s
  outfile << s << "\n";
}

Now all you have to do is find every '|' and replace each one with a ','.

This method assumes something important: no field (the text between pipes) can contain either a pipe or a comma. If the input can contain such fields, then the conversion becomes a bit more complicated, and you need a different way of handling the changes.

Let me know.
Last edited on
in between the fields I can find some commas. what i did is: i find the commas and replace them by * then enclose the field containing the commas in " " double quotes. with these codes:
int result = 0;
int length = input_sz.length();

while ( result != string::npos )
{
if (result < length)
{
result = input_sz.find(",",result);
if (result != -1)
{
the_string = input_sz.erase(result, 1);
the_string = input_sz.insert(result, "*");
}
}
}
------------------------------------------
the second set of if statement enclose them in ""


I thought about using the class FileConverter then I give up. it's not really doing anything. i will remove it when I'm tweaking the code.
Please use [code] tags.

re: FileConverter -- why wait? Remove it now. Code is easiest to follow when decluttered.


I don't know what "the_string" is, but you should be messing directly with "input_sz":

1
2
3
4
5
6
result = input_sz.find( "," );
while ( result != string::npos )
{
  input_sz[ result ] = '*';
  result = input_sz.find( ",", result );
}

This has the caveat that your input cannot ever have a '*' in it. Are you sure that it doesn't?

You might be better off just find()ing the pipes '|' and splitting the string out from that
(using substr( previous_result + 1, result - previous_result - 1 )).

Once you have split the substring out, you can simply check to see if it has any characters that need quoting. If it does, add double-quotes to the ends of the string.

1
2
3
4
if (the_substring.find( "," ) != string::npos)
{
  the_substring = '"' + the_substring + '"';
}


All this substring stuff can be made easier by using an istringstream and another loop with getline(), this time stopping at a pipe instead of a newline:

1
2
3
4
5
  istringstream ss( input_sz );
  while (getline( ss, the_substring, '|' ))
  {
    ...
  }


In any case, there is still one possible caveat. Is it possible that your input has quoted fields? Stuff like:

    hello|"world|everyone"|""""

which is three fields:

    hello
    world|everyone
    "


If it does, then you'll need to adjust your reading approach.
Topic archived. No new replies allowed.