Text.txt file seperation into 2 seperate text.txt files with chars involved

Hey guyss. Good evening.

I was trying to write the code as best I could but It didnt work out.
A AV1538
A AV9981
K KA8136
A AV4687
K KA9882
K KA2136
A AV5136
A AV8662
K KA8792
A AV1368
K KA5633
A AV6549
A AV7823

AV1538
AV9981
AV4687
AV5136
AV8662
AV1368
AV6549
AV7823

KA8136
KA9882
KA2136
KA8792
KA5633

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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>

using namespace std;
//---------------------------------------
void FileRead (int &n, int a, char A[]);
void FileWrite (int n, char A[]);
//---------------------------------------
int main ()
{
    
    char n, a, A[100];

    
    return 0;
}
//--------------------------------------
void FileRead ( int &n, char a, char A[])
{
    ifstream df ("code.txt");
    df >> n; // - how many lines ( 13)
    for ( int i = 0; i < n; i++) df >> a >> A[i];// ( the letter of the code, the other letters and numbers are the serial code);
    
    
}
void FileWrite( int n, char a, char A[])
{
    ofstream rf ("FileA.txt");
    ofstream rf ("FileiB.txt");
    
    for ( int i = 0; i < n;i++) if( a = 'A') rf << ("FileA.txt") << endl;
    else rf << ("FileB.txt") << endl;
        
}

Bear in mind im a begginer and I don't know all of the code. I've only discovered symbols with char() stuff.
Any help would be appreciated.
Last edited on
Lines 15:16: You never call your read and write functions.

Lines 30,31: Your compiler should be complaining about duplicate symbol names.
You want:
1
2
  ofstream rfa ("FileA.txt");
  ofstream rfb ("FileB.txt");  //  Note you had an extraneous i in the file name. 


Line 33: (a = 'A') Is an assignment. You want the comparison operator ==.

Line 33: rf << ("FileA.txt") << endl; That's not the correct syntax for an output operation.
You want to output A[i].
 
    rfa << A[i] << endl;

Line 34: Ditto.
 
    rfb << A[i] << endl;

Last edited on
Make sure to turn up the compiler warning levels as high as you can and read the messages you get. The first one is the most important.

In this case, it should complain that you are attempting to create two variables named rf. You can’t do that.

To separate text into two files, one with lines starting with A and the other with lines starting with K:

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
#include <cctype>
#include <fstream>
#include <iostream>
#include <string>

int main()
{
  std::ifstream inf( "code.txt" );
  std::ofstream outfA( "codeA.txt" );
  std::ofstream outfK( "codeK.txt" );
  std::string s;
  while (getline( inf, s ))
  {
    switch (toupper( s.c_str()[0] ))
    {
      case 'A': outfA << s << "\n"; break;  // A lines go only to file A
      case 'K': outfK << s << "\n"; break;  // K lines go only to file K
      case '\0': // blank lines go to both A and K
        outfA << "\n";
        outfK << "\n";
        break;
      default: // all other lines are ignored
        break;
    }
  }
}

Hope this helps.
I really don't understand the most of code that you've written
The ones im confused with are getline, case, toupper s.c_str , switch.

The only tricky thing is the c_str part — so that if the string is an empty string there isn’t an out-of-bounds access but it will find the null-terminator for the string. It could be / should have been written thus:

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
#include <fstream>
#include <iostream>
#include <string>

int main()
{
  std::ifstream inf( "code.txt" );
  std::ofstream outfA( "codeA.txt" );
  std::ofstream outfK( "codeK.txt" );
  std::string s;
  while (getline( inf, s ))
  {
    if (s.empty())
    {
        outfA << "\n";
        outfK << "\n";
    }
    else if ((s[0] == 'A') or (s[0] == 'a'))
    {
      outfA << s << "\n";
    }
    else if ((s[0] == 'K') or (s[0] == 'k'))
    {
      outfK << s << "\n";
    }
  }
}

The rest of it is very basic C++ file I/O, which you need to be familiar with to make anything useful happen. Try googling around the terms and reading a C++ tutorial. A good one to start with is https://www.learncpp.com/.

Good luck!
Last edited on
A AV1538


Is this actually the format of the input file - with a type letter followed by a space followed by the data? If yes, then when you write the data to the other files you'll need to remove the initial letter and space.
Ah, I misunderstood the task. How about this?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <fstream>
#include <iostream>
#include <string>

int main()
{
  std::ifstream inf( "code.txt" );
  std::ofstream outfA( "codeA.txt" );
  std::ofstream outfK( "codeK.txt" );
  std::string s;
  while (getline( inf, s ))
    if (!s.empty())
    {
      if      (s[0] == 'A') outfA << s.substr( 2 ) << "\n";
      else if (s[0] == 'K') outfK << s.substr( 2 ) << "\n";
    }
}
If you want/need separate functions for reading/writing the file data:
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
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <cctype>

void ReadData(std::ifstream&, std::vector<std::string>&);
void WriteData(std::ofstream&, const std::string&);

int main()
{
   // open the input & output files
   std::ifstream df  { "code.txt" };
   std::ofstream ofa { "FileA.txt" };
   std::ofstream ofk { "FileK.txt" };

   // create a vector to hold the read data as strings
   std::vector<std::string> data;
   
   ReadData(df, data);

   // a range-based for loop to access each vector element
   for (const auto& itr : data)
   {
      // determine if the data is a 'A' or 'K'
      if (toupper(itr[0]) == 'A')
      {
         WriteData(ofa, itr);
      }
      else
      {
         WriteData(ofk, itr);
      }
   }

   std::cout << "Done!\n";
}

void ReadData(std::ifstream& is, std::vector<std::string>& data)
{
   std::string data_type;
   std::string data_str;

   while (is >> data_type >> data_str)
   {
      data.push_back(data_str);
   }
}

void WriteData(std::ofstream& os, const std::string& str)
{
   os << str << '\n';
}

I use a std::vector so I can read the data in one pass. This is a quick slap-dash bit of code that could be tweaked for better efficiency.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <fstream>
#include <iostream>
#include <string>
#include <utility>

int main() {
	std::ifstream inf("code.txt");
	std::ofstream out[2] {std::ofstream("codeA.txt"), std::ofstream("codeK.txt")};

	if (!inf || !out[0] || !out[1])
		return (std::cout << "Error opening files\n"), 1;

	for (auto [c, s] {std::pair {char {}, std::string {}}}; (inf >> c >> std::ws) && std::getline(inf, s); )
		if (unsigned f = (c - 'A') / ('K' - 'A'); f < 2)
			out[f] << s << '\n';
}

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
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>

using namespace std;
//---------------------------------------
void file (int &n, int a, char A[]);
void write (int n, char A[]);
//---------------------------------------
int main ()
{

    char n, a, A[100];

    ifstream df ("file.txt");
    ofstream rfa ("codeA.txt");
    ofstream rfb ("codeK.txt");

    return 0;
}
//--------------------------------------
void file ( int &n, char a, char A[])
{
    ifstream df ("file.txt");
    df >> n;
    for ( int i = 0; i < n; i++) df >> a >> A[i];


}
void write ( int n, char a, char A[])
{
    ofstream rfa ("codeA.txt");
    ofstream rfb ("codeK.txt");

    for ( int i = 0; i < n;i++) if( a == 'A') rfa << A[i] << endl;
    else rfb << A[i] << endl;

}


I still don't know where im wrong. I've tried the things I understood but the other code stuff was a bit out of reach on my end. It just doesnt even print out anything now, but It makes 2 txt files now
A large chunk of what is going wrong is you are using a single C string as if it were an array of C strings, accessing the individual elements of the char array trying to insert/extract more than one character.

A refresher on what C strings are:
https://www.learncpp.com/cpp-tutorial/c-style-strings/

That is why I went with std::vector and std::string, to read and hold the alphanumeric chunk of data on each line after the single character and the space. Plus, using a vector it is easy to retrieve the number of stored elements. Same for a C++ string. C strings, especially an array of C strings, requires a lot of manual tracking.

char vs. int, don't mix and match them.
https://www.learncpp.com/cpp-tutorial/chars/

Another biggie why things aren't working as you expect, you never actually call the functions.
https://www.learncpp.com/cpp-tutorial/introduction-to-functions/

Another thing to note, use more descriptive variable names, they self-document what the code is doing.

'n' really doesn't 'tell' us what is it used for. 'num_elems' (a guesstimation of use on my part) does document that it holds the number of used elements in some array.
Why do you need the initial character in each input line? It seems to match the first character of the subsequent string anyway.


Here's another one to add to the confusion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <fstream>
using namespace std;

int main ()
{
   ifstream in  ( "file.txt"  );
   ofstream rfA ( "codeA.txt" );
   ofstream rfK ( "codeK.txt" );
   char c;
   string code;
   while ( in >> c >> code ) ( c == 'A' ? rfA : rfK ) << code << '\n';
}

Last edited on
Why do you need the initial character in each input line?

I suspect it is some weird assignment thingie, maybe. To test how a student deals with sub-strings. Maybe.

Stranger school/uni requirements have shown up, for sure.
Topic archived. No new replies allowed.