Jump to content
  • Advertisement
Sign in to follow this  
nickme

C++ what is in string after std::istreambuf_iterator< char >(sourceFile))

This topic is 697 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

 

I tried to print an text input file and print the line numbers and the line to stdout.  I used std::istreambuf_iterator, but I want to know what its char did it produced. here is the codes that I load the input file.

char * loadFromFile(char * file)
{
	//Open file
	std::string s;
	std::ifstream sourceFile(file);

	if (sourceFile)
	{
		s.assign((std::istreambuf_iterator< char >(sourceFile)),
				  std::istreambuf_iterator< char >());
	}
	else {
		printf("Eror in openning file [%s].\n", file);
		system("pause");
		exit(1);
	}
	return (char*) (s.c_str());
}

when i tried to print the whole char *stream, i got looping until it crashed.  Here is the print func.

void print_string(char *ins) {
	char *c, *ac;
	int i = 1;

	for (c = ins; *c != '\0'; i++) {
		printf(" %06i : ", i);
		for (ac = c; *ac != '\n' || *ac != '\0'; ac++)
			putchar(*ac);
		putchar('\n');
		c = ++ac; // skip the '\n'
	}

}

thank in advance

 

Share this post


Link to post
Share on other sites
Advertisement
Did you step through the code in your debugger?

 

 

HI ApochPiQ,

 

thanks for the reply.

 

I did used the debugger.  when i was in the debugger, the content of *c and *ac are all strange looking char, It is not from my input file.

 

If i printf(the output string loadFromFile()) in the main func, it showed the text in my file with garbage.  i can not use the printf or cout statement becaue i want to print line numbers at the beginning of each lines.

 

the main func :

int main() {
	char * stream = loadFromFile(infile);
	std::cout << stream << std::endl;
//pe(stream);
	system("pause");
	print_string(stream);
}
Edited by nickme

Share this post


Link to post
Share on other sites

I did used the debugger. when i was in the debugger, the content of *c and *ac are all strange looking char, It is not from my input file.

Is the file loaded correctly inside loadFromFile? (Hint, the issue is inside loadFromFile.)

Share this post


Link to post
Share on other sites

Is the file loaded correctly inside loadFromFile? (Hint, the issue is inside loadFromFile.)

 

the print out in loadFromFile() (s.c_str()) looked correctly as in my input file, It was when I print the stream in main() that show garbage.

Share this post


Link to post
Share on other sites

Your function: char * loadFromFile(char * file)

 

returns char pointer which points to local variable s (std::string). That s variable goes out of scope at the end of your function, hence you get garbage. C++ is already hard language and adding usage of raw char to it is asking for trouble. Do yourself a favor and use std::string instead of char *.

 

Some reading to get you started at http://en.cppreference.com/w/cpp/language/scope

Share this post


Link to post
Share on other sites

hi DoctorGlow,

 

thanks for the reply.

 

now my stream is not garbage anymore.  In the print_string(), when *ac = '\n', the inner nested for loop did not break.  In my nested loop, it suppose to get out of the loop when *ac = '\n', why is that.

 

here is my entire project:

#include <stdio.h>
#include <string>
#include <fstream>
#include <iostream>

#define infile "in.txt"

std::string loadFromFile(char * file)
{
	//Open file
	std::string s;
	std::ifstream sourceFile(file);

	if (sourceFile)
	{
		s.assign((std::istreambuf_iterator< char >(sourceFile)),
				  std::istreambuf_iterator< char >());
	}
	else {
		printf("Eror in openning file [%s].\n", file);
		system("pause");
		exit(1);
	}
	return s;
}

void print_string(char *ins) {
	char *c, *ac;
	int i = 1;

	for (c = ins; *c != '\0'; i++) {
		printf(" %06i : ", i);
		for (ac = c; *ac != '\n' || *ac != '\0'; ac++)
			putchar(*ac);
		putchar('\n');
		c = ++ac; // skip the '\n'
	}

}

void pe(char *c) {
	char *t = c;
	while (*t != '\0') {
		putchar(*t);
		t++;
	}
}

int main() {
	std::string stream = loadFromFile(infile);
//	std::cout << stream << std::endl;
//pe(stream);
//	system("pause");
	print_string((char *)stream.c_str());
}

Share this post


Link to post
Share on other sites

Using C++-style casts, instead of dangerous C-style casts, would've also helped highlight the problem.

 

By doing this:

return (char*) (s.c_str());

That's already an indicator that something was wrong, but the (char*) is telling the compiler to shut up and stop telling you that it's wrong.  :)

When you type (char*) or similar, you're saying, "I know you think this is wrong, Mr Compiler, but trust me - I know better than you, just do it anyway.". You disabled the safeguards. 

 

Or, to put it in more technical terms, you unlocked the cage and the raptor ate your face.  :P

 

C++-style casts are also disabling safeguards, but in a more controlled way, whereas (char*)-style casts disable every type-conversion safeguard at once.

We've all been bitten by that kind of mistake numerous times; this is the C++ learning process.  :wink:

Share this post


Link to post
Share on other sites

My error: the for loop should looked like this:

 

for (ac = c; *ac != '\n' && *ac != '\0'; ac++)  // the && solved the problem.
 
how ever, the loop also read 2 line passed the end of file, do you have any idea why?

Share this post


Link to post
Share on other sites

hi

 

I finally solved my problem.  the print_string() is now :


void print_string(char *ins) {
	char *c, *ac;
	int i = 1;

	for (c = ins; *c != '\0'; i++) {
		printf(" %06i : ", i);
		for (ac = c; *ac != '\n' && *ac != '\0'; ac++)
			putchar(*ac);
		putchar('\n');
		if (*ac != '\0')
			c = ++ac; // skip the '\n'
		else
			c = ac;
	}

}


thanks

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!