Program to format and organize files, outputs blank files

Hello everyone! I assumed that this would be more of an elementary problem, as I'm not receiving any errors, but rather just blank files. But anyway, this is the meat of the program:

1 - asks for the "root" directory, where all the manipulating will take place.
2 - takes all the file names into a string called fileNames (full definition within code).
3 - Organizes the files into sub-directories of their locations (ie: AC, AW, BR...).
4 - Manipulates the files using this function, called Execution.

The following have already been called and defined:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <fstream>
#include <string>
#include <direct.h>
using namespace std;

char fileNames[43630][20];
char path[MAX_PATH+1];
char root[MAX_PATH+1];
char country[43631][2];
char dirName[MAX_PATH+1];
int slength=0;
int z=0;
bool done=0;
char realPath[MAX_PATH+1];


Here's the code for the function Execution:

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
void Execution(string LOCATION){
	 //----- -----------------------        WHILE YOU'RE IN THE FILE
	 int count=0,i=0;
	 ifstream input(LOCATION.c_str());
	 ofstream output(LOCATION.c_str());
	 if(input.fail()){
                 cout << "Error opening file." << endl;
                 exit(1);}
	 char String[301];
	 while(count!=38){
        
        
		// --------------------------------
		 input.getline(String,12);       // This block of code allows me to separate the pieces of information 
		 output << String; // meshed together initially so that it becomes more readable
		 for (z=0; z<2;z++)
			 country[slength][z]=String[z];
		 input.seekg(11);
		 input.getline(String,5);
		 output << " " << String;
		 input.seekg(15);
		 input.getline(String,3);
		 output << " " << String;
		 input.seekg(17);
		 input.getline(String,5);
		 output << " " << String;
		 input.seekg(20);
		// -----------------------------
		 input.getline(String,300,'\n'); // going to manipulate the string
		 for(int a=0; a<sizeof(String); a++){
			 if(String[a]==('T' || 'S' || 'I')){
				if(String[a]==('X' || 'T' || 'S' || 'I'))
					String[a-1]=' ';
				String[a]=' ';}
		 }
		 output << String;
		 output << endl;
		// -------------------------------
		count++;
	 }
	  input.close();
    output.close();	
	 
	//-------------------- EXITING THE FILE
}  


Thanks for any help you can give me!
Unless I'm mistaken, line 5 clears the contents of the file.
Either use just one file for both input and output by opening it as std::fstream; or first read the entire file to memory, close it, then open it for output.
Oh haha, thanks. :)
How would I read the entire file to memory? Strings?
That's one way. Since an std::string is basically a glorified std::vector, an std::vector<char> would also work. Still another, if worse, option is a raw array of chars.
Take a look at std::ifstream::read(), although I can't remember ATM if it works for text files.
Thanks again! I think I've got it, but it takes several hours so we'll see how it pans out. Here's my final code:

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
void Execution(string LOCATION){ // formats the file into the desired format
	 //----- -----------------------        WHILE YOU'RE IN THE FILE
	 int count=0,i=0;
	 ifstream input(LOCATION.c_str());
	 sprintf(tempFile,"%s\\tempFile",root);
	 ofstream output(tempFile, ios::trunc);
	 if(input.fail()){
                 cout << "Error opening file." << endl;
                 exit(1);}
	 char String[301];
	 while(!output.eof()){
        
        
		// --------------------------------
		 input.getline(String,12);       // This block of code allows me to separate the pieces of information 
		 output << String; // meshed together initially so that it becomes more readable
		 input.seekg(11);
		 input.getline(String,5);
		 output << " " << String;
		 input.seekg(15);
		 input.getline(String,3);
		 output << " " << String;
		 input.seekg(17);
		 input.getline(String,5);
		 output << " " << String;
		 input.seekg(20);
		// -----------------------------
		 input.getline(String,300,'\n'); // going to manipulate the string
		 for(int a=0; a<sizeof(String); a++){
			 if(String[a]==('T' || 'S' || 'I')){
				if(String[a]==('X' || 'T' || 'S' || 'I'))
					String[a-1]=',';
				String[a]=' ';}
		 }
		 output << String;
		 output << endl;
		// -------------------------------
		count++;
	 }
	input.close();
    output.close();
if (!copyFile (tempFile, LOCATION.c_str()))
        cout << "File could not be copied successfully";
    else
        cout << "File copied successfully!";
	 
	//-------------------- EXITING THE FILE
}  
I ran the code a couple times yesterday and today, and I'm running into problems again :(. I get this message when I run it:

Unhandled exception at 0x1029984f (msvcr90d.dll) in Objective I.exe: 0xC0000005: Access violation reading location 0x82c85302.

Here's my entire program:

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <fstream>
#include <string>
#include <direct.h>

using namespace std;

int	 z=0, a=0, slength=0, file_country[23151];
char fileNames[23151][20], country[23151][2];
char path[MAX_PATH+1], root[MAX_PATH+1], dirName[MAX_PATH+1],
	 realPath[MAX_PATH+1], tempFile[MAX_PATH+1];
bool done=0;




bool copyFile (const char SRC[], const char DEST[]) // copies a file's contents into another
{
    ifstream src; // the source file
    ofstream dest; // the destination file
    src.open (SRC, ios::binary); // open in binary to prevent jargon at the end of the buffer
    dest.open (DEST, ios::binary); // same again, binary
    if (!src.is_open() || !dest.is_open())
        return false; // could not be copied
    dest << src.rdbuf (); // copy the content
    dest.close (); // close destination file
    src.close (); // close source file
    return true; // file copied successfully
}




int rir(bool bCountHidden = false) //puts file names into the string fileNames[][]
{
	WIN32_FIND_DATA fd;
	DWORD dwAttr = FILE_ATTRIBUTE_DIRECTORY;
	if(!bCountHidden) dwAttr |= FILE_ATTRIBUTE_HIDDEN;
	sprintf( path, "%s\\*", root);
	HANDLE hFind = FindFirstFile( path, &fd);
	if(hFind != INVALID_HANDLE_VALUE)
	{
		int count=0,k=0;
		do
		{
			if( !(fd.dwFileAttributes & dwAttr)){
				strcpy(&fileNames[k][0],fd.cFileName);
				strncpy(&country[k][0],fd.cFileName,2);
				puts(fd.cFileName);
				k++;
			}
		} while( FindNextFile( hFind, &fd));
		FindClose(hFind);
		return count;
	}
	return -1;
}




	void Execution(string LOCATION){ // formats the file into the desired format
	 //----- -----------------------        WHILE YOU'RE IN THE FILE
	 int i=0;
	 ifstream input(LOCATION.c_str());
	 sprintf(tempFile,"%s\\tempFile",root);
	 ofstream output(tempFile, ios::trunc);
	 if(input.fail()){
                 cout << "Error opening file." << endl;
                 exit(1);
	 }
	 char String[301];
	 while(!output.eof()){
        
        
		// --------------------------------
		 input.getline(String,12);       // This block of code allows me to separate the pieces of information 
		 output << String; // meshed together initially so that it becomes more readable
		 input.seekg(11);
		 input.getline(String,5);
		 output << " " << String;
		 input.seekg(15);
		 input.getline(String,3);
		 output << " " << String;
		 input.seekg(17);
		 input.getline(String,5);
		 output << " " << String;
		 input.seekg(20);
		// -----------------------------
		 input.getline(String,300,'\n'); // going to manipulate the string
		 for(int a=0; a<sizeof(String); a++){
			 if(String[a]==('T' || 'S' || 'I')){
				if(String[a]==('X' || 'T' || 'S' || 'I'))
					String[a-1]=',';
				String[a]=' ';}
		 }
		 output << String << endl;
	 }
	input.close();
    output.close();
if (!copyFile (tempFile, LOCATION.c_str()))
        cout << "File could not be copied successfully";
    else
        cout << "File copied successfully!";
	 
	//-------------------- EXITING THE FILE
}  

	void Organize(string LOCATION){ // organizes the unformatted files into directories by country
		for(slength=0; slength<23150;slength++){
			sprintf(dirName,"%s\\%s",root,&country[slength][0]);
			CreateDirectory(dirName,NULL);
		}
		for(slength=0; slength<23150;slength++){
			done=0;
			for(z=0;z<23150;z++){
				if(strncmp(&fileNames[slength][0],&country[z][0],2)==0){
					file_country[slength]=z;
					done=1;
					sprintf(path,"%s\\%s",root,&fileNames[slength][0]);
					sprintf(dirName,"%s\\%s",root,&country[slength][0]);
					sprintf(realPath,"%s\\%s",dirName,&fileNames[slength][0]);
					MoveFile(path,realPath);
				}
				if(done=1) break;
			}
		}

	}




 
int main(int argc,char** argv){
	cout << "GHCND_obj v0.8\n\n" << endl;
	cout << "Please give the path of the directory which contains .dly files, ghcnd-stations.txt, and ghcnd-countries.txt(no spaces)"<< endl;
	cout << "(ie: z:\\kayiita\\GHCND_data\\DATA\\ghcnd_all):"<< endl;
	cin >> root;
	rir(0);
	cout << "Now organizing files into their respective country directories\nPlease wait until the program terminates."<< endl;
	Organize(root);
	for(slength=0; slength<23150; slength++){
		sprintf(realPath,"%s\\%s\\%s", root, &country[file_country[slength]][0],&fileNames[slength][0]);
		Execution(realPath);
		if(slength==0)
			cout << slength+1 << "file has been manipulated." << endl;
		else cout << slength+1 << " files have been manipulated."<< endl;
	}
	
	cout << "Objective I completed." << endl;
	return 0;
}
	 


Thanks in advance!
I'm guessing you have an out of bound access error somewhere...step through it with a debugger until you find where it dies (or you can try clicking "break")
I stepped with the MS Visual Studios debugger and it breaks when the main function tries executing my Organize(string) function.

here's the error it gives me:


 
Unhandled exception at 0x1029984f (msvcr90d.dll) in Objective I.exe: 0xC0000005: Access violation reading location 0x82c85302. 



1
2
3
4
5
6
       text.sz = __nullstring;
                    p = text.sz;
                    while (i-- && *p)
                        ++p;
                    textlen = (int)(p - text.sz);    /* length of the string */
                }

it's in output.c and the arrow's at the ' while ( i-- && *p) ' when it breaks


If someone could help me further on this, I would really appreciate it. Is it possibly that my buffer is too small? But when i go to the address/location of dirName (entered &dirName in memory1 via Visual Studios) it has a whole bunch of the country elements entered, and a large part of it is in red lettering.

Thanks!

(Added)

Additionally, this is what i get when I look at the address of path (&path) during the rir(0) function execution:

1
2
3
4
5
6
7
8
7a 3a 5c 6b 61 79 69 69 74  ..............................z:\kayiit
0x0041B571  61 5c 47 48 43 4e 44 5f 64 61 74 61 5c 44 41 54 41 5c 67 68 63 6e 64 5f 61 6c 6c 5c 2a 00 fe fe fe fe fe fe fe fe fe  a\GHCND_data\DATA\ghcnd_all\*.þþþþþþþþþ
0x0041B598  fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe  þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ
0x0041B5BF  fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe  þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ
0x0041B5E6  fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe  þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ
0x0041B60D  fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe  þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ
0x0041B634  fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe  þþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþþ
0x0041B65B  fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  þþþþþþþþþþþþþþþþþþ
Last edited on
I'm assuming text.sz is a pointer...anyway, I think that it is not null terminated, so you get don't ever stop incrementing p.
I discovered the problem! my "country" two dimensional character array did not leave room for the null terminator, and so the strings ran together so I would end up with extremely large names for directory's, which caused the debugger to break. I made the [][2] for the character array into [][5], and now it's running smoothly! Thanks for everyone's help!
Topic archived. No new replies allowed.