Hello all! This is my first post to community!

I've been writing a program in C++ (not MFC) to get a NTFS ADS file and copy it to desktop. If you don't know what ADS file is, you don't really have to matter, let's say that this program must just copy any file (by giving path) to desktop. Here is the first part of the program in which there is a runtime error :

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

int main(int argc,char *argv[]){
	char argv2[100]; //will store argv[1] (path)
	strcat(argv2,argv[1]);
	int wher=0;
	char ch;
	system("cmd /c echo \"%userprofile%\\desktop\" >c:\\ads.txt"); //will write the path of desktop in c:\ads.txt
	ifstream ifs("c:\\ads.txt",ios::in & ios::binary); //open ads.txt to read where desktop is
	char newfile[100];
	while(ifs){
		ifs.get(ch);
		if(ifs){ newfile[wher]=ch;
		wher++;}}
	ifs.close();	
	int when=0;
	while(newfile[when]) when++; //gets "newfiles" length 
	char newfile2[100];
	for(int b=0;b<=when-1;b++) newfile2[b]=newfile[b]; //copies anything except the last quote ( ' " ' ) (at least,that's what I want)
	system("del c:\\ads.txt /q");
	strcat(newfile2,"\\newfile\"");//new we should have the path of the "newfile" at desktop
	ifstream in(argv2,ios::in & ios::binary);
	ofstream out(newfile2);
	out << in.rdbuf();//write source file in target ("newfile") file
	out.close();
	in.close();}
}

The second part is just for the extension of the "newfile". When I try to run this (by creating .exe),I get the following error:
Debug Assertion Failed
Program:[the path of .exe]
File:f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c
Line:1317
Expression:_CrtIsValidHeapPointer(pUserData)
For information bla bla bla

I know it has to do something with the heap, but I tried everything I could. Any help would be appreciated. Thanks everybody in advance! :) If you have ANY question ask me.

Edited 6 Years Ago by 'AnKo: n/a

while(newfile[when]) when++; //gets "newfiles" length

Does not do what you think you want it to. It stops at the first char with value 0, which might be a value in the date that occurs before the end the input file, but is not guaranteed to mark the end of your newfile. The loop keeps going till it finds a char value 0, which in my testing, happens some 11 char's past the end of the array, into which I'd only stored 5 char's.!!!

Why not keep a counter as you read the data, then you'll already know how much data is in the array? Guess what, your "wher" variable does that.

You could also reduce repetition in your reading loop by using the read action as the loop condition, like:

while( ifs.get(ch) )
  {
     newfile[wher]=ch;
      wher++;
  }

You should test wher before reading to ensure you have room to store what you read.

strcat(newfile2,"\\newfile\"")

newfile2 does not have a null terminator (byte valued 0), so the strcat tacks stuff on where????

Last note

ifstream ifs("data.txt",ios::in & ios::binary);

Normally the bitwise OR ( | ) is used to join the different IOS flags

Comments
Many find points for the OP to consider here!

Really thx man, I had some mad mistakes. For the first remark I used

when=strlen(newfile)

, for the second... I didn't really understand. Don't

while(ifs){
ifs.get(ch);
if(ifs){ newfile[wher]=ch;
wher++;}}

works okay? And also, I don't need to test wher for if I have enough space, because it is used only to read a path, maximum 80 bytes. For the strcat issue, I tried this

newfile2[wher]='0';

above the strcat, should it work? And as for the last mistake... I really should see some kind of doc. Thx again. Despite all these, I still have the same problem. Any ideas, guys?

Edited 6 Years Ago by 'AnKo: n/a

Have you thought about forgetting the char arrays and using std::string instead? Consider for example

// Read in the line from data.txt, in one go
string line;
ifstream ifs("data.txt", ios::in | ios::binary);
if(getline(ifs, line))
{
  cout << "read: " << line << endl;
}

But if you insist on using char arrays, then fix the first strcat() by replacing it with strcpy() , so ..

char argv2[ <a reasonably large value here > ]; //will store argv[1] (path)
strcpy(argv2,argv[1]);

The way you have it, is definitely wrong, argv2 is uninitialized there and the strcat() is likely to end up trashing memory.

At any rate, be prepared for paths longer than 80 chars, a reasonable max path length would be 260 chars (which is MAX_PATH on Windows).

Another tip to keep you out of trouble is to always initialize your char arrays, just like you should initialize any variable.

char argv2[100] = "";  //two double quotes, no space between them - an empty string

Now you have an array that is full, all the way to the end, with NULL terminators (byte value 0).

That is not the same as assigning character '0'.

newfile2[wher]='0';   //still does not terminate the string!!!

You just put the char '0' at the last position, but are not assured the string is terminated.

newfile2[wher]='\0';  //now you've terminated it

Yet one more thing, if/when you do strcpy(argv2, argv[1]); you want to check that there actually is an argument available, you can use argc for that.

Thank you all mates! I solved it. Actually, I now got another problem cause rdbuf() don't seem to copy the binary or at least .exe - photo files normally, but that's another story! :) I'll find it myself, too easy. If anybody wants to take a look at my code for inspire or anything, here it is. Again thx anybody! [EDIT: I edit this and works even with .exe . I'd just forgotten the ios::out | ios::binary at ofstream :D! Anyway, it's really helpful for ADS, if you know what is.]

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

int main(int argc,char *argv[]){
	char argv2[200]="";
	strcpy(argv2,argv[1]);
	int wher=0;
	char ch;
	system("cmd /c echo %userprofile%\\desktop >c:\\ads.txt");
	ifstream ifs("c:\\ads.txt",ios::in | ios::binary);
	char newfile[200];
	ifs >> newfile;
	ifs.close();
	system("del c:\\ads.txt");
	strcat(newfile,"\\newfile");
	ifstream in(argv2,ios::in | ios::binary);
	ofstream out(newfile,ios::out | ios::binary);
	out << in.rdbuf();
	out.close();
	in.close();
//:::::::::::::::::::::::::::::::Second Part (Extension)
	char ext[10];
	int num=0;
	int num2=1;
	while(argv2[num]) num++;
	for(int a=0;a<=4;a++){
		ext[num2-1]=argv2[num-num2];
		num2++;}
	char ext2[10]="";
	ext2[0]=ext[3];
	ext2[1]=ext[2];
	ext2[2]=ext[1];
	ext2[3]=ext[0];
	char argv3[100]="ren \"%userprofile%\\desktop\\newfile\" newfile";
	if (!strcmp(ext2,"html")) strcat(argv3,".html");
	else if (!strcmp(ext2,"jpeg")) strcat(argv3,".jpeg");
	else if (!strcmp(ext2,"pict")) strcat(argv3,".pict");
	else if (!strcmp(ext2,"mpeg")) strcat(argv3,".mpeg");
	else if (!strcmp(ext2,"moov")) strcat(argv3,".moov");
	else if (!strcmp(ext2,"midi")) strcat(argv3,".midi");
	else if (!strcmp(ext2,"aiff")) strcat(argv3,".aiff");
	else if (!strcmp(ext2,"wave")) strcat(argv3,".wave");
	else if (!strcmp(ext2,"mime")) strcat(argv3,".mime");
	else if (!strcmp(ext2,"tiff")) strcat(argv3,".tiff");
	else strcat(argv3,ext2);
	system(argv3);
	return 0;
}

Edited 6 Years Ago by 'AnKo: n/a

This question has already been answered. Start a new discussion instead.