Trouble with garbage chars in visual c++ file reading - visual-c++

I am trying to read a text file using the following code:
void function readfile(char *inputfile) {
istream is;
int filesize = 0;
is.open(inputfile);
if (!is.is_open()) {
return;
}
is.seekg(0, ios::end);
filesize = (int)is.tellg();
is.seekg(0, ios::beg);
char *buf = new char[filesize];
is.read(buf, filesize);
is.close();
cout << buf << endl;
delete[] buf;
return;
}
While in g++ (mac / macports) it works correctly (getting all contents into a dynamic allocated char* array), in Visual Studio C++ 2010, I get constant errors of this type: Debug assertion failed: (unsigned)(c+1) <= 256, file isctype.c.
The problem is that it opens the file but can't find a termination delimeter so when it reaches the eof it starts reading somewhere else (garbage characters). Using the cout << buf; I can see that the file is being read correctly in mac but in visual c++ it types more garbage chars. What is the problem here?

Make your buffer one larger and add the terminating nul yourself.

Let C++ standard library do the work for you:
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
See, it's now also
exception safe
handles embedded NUL characters correctly
Note, of course you can use vector instead of string if you prefer (just change that one word)
Full demo: see it live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::string buf(std::istreambuf_iterator<char>(is), {});
std::cout << buf << std::endl;
}
int main()
{
readfile("main.cpp");
}
Update For C++11 challenged compilers (and showing how to use a vector):
Also Live on Coliru
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
void readfile(const char *inputfile) {
std::ifstream is(inputfile);
std::istreambuf_iterator<char> f(is), l;
std::vector<char> buf(f, l);
std::cout.write(buf.data(), buf.size());
}
int main()
{
readfile("main.cpp");
}

Related

How to print eight words to a line using vector<string>?

I was trying to make a program write 8 words to a line after a user enter their sentence.Its only printing words that have been typed in and i don't have a clue how to make it type 8 words to a line.
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
using namespace std;
vector<string> sentence;
string sente = "";
void print(string, string);
template<typename T>
void print(vector<T>& v, string)
{
cout << "Enter your sentence " << endl;
getline(cin, sente);
sentence.push_back(sente);
for (auto const elem: sentence)
{
cout << elem;
}
}
int main()
{
print(sentence,sente);
}
Using global variables is generally not a good practice.
Also you don't need a extra vector for your use case.
Take a look at the following code, where you can smartly make use of istringstream for your use case:
#include <iostream>
#include <string>
#include <sstream>
void print()
{
std::string sente;
std::cout << "Enter your sentence " << std::endl;
getline(std::cin, sente);
// Used to split string around spaces.
std::istringstream ss(sente);
int wordCountPerLine = 0;
int requiredWordsPerLine = 8;
// Traverse through all words
do {
// Read a word
std::string word;
ss >> word;
// Print the read word
std::cout << word << " ";
wordCountPerLine++;
if(wordCountPerLine % requiredWordsPerLine == 0){
std::cout<<std::endl;
wordCountPerLine = 0;
}
// While there is more to read
} while (ss);
}
int main()
{
print();
}
Feel free to ask any doubts.

C++ portability from Windows to Linux

I have been successfully using the following code in C++ on Windows (via CodeBlocks) and have recently attempted to use the same code on Linux (Ubuntu 18.04) also via CodeBlocks. The code appears to compile fine but fails on execution.
The purpose of the code is to import a comma delimited text file of numbers into an array.
In both Windows and Linux I am using the GNU GCC Compiler.
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <cstdio>
#include <stdlib.h>
using namespace std;
typedef vector <double> record_t;
typedef vector <record_t> data_t;
istream& operator >> ( istream& ins, record_t& record)
{
record.clear();
string line;
getline( ins, line );
stringstream ss( line );
string field;
while (getline( ss, field, ',' ))
{
stringstream fs( field );
double f = 0.0;
fs >> f;
record.push_back( f );
}
return ins;
}
//-----------------------------------------------------------------------------
istream& operator >> ( istream& ins, data_t& data )
{
data.clear();
record_t record;
while (ins >> record)
{
data.push_back( record );
}
return ins;
}
//-----------------------------------------------------------------------------
int main()
{
data_t data;
ifstream infile( "Import File.txt" );
infile >> data;
if (!infile.eof())
{
cout << "Unsuccessful Import!\n";
return 1;
}
infile.close();
cout << "Your file contains " << data.size()-1 << " records.\n";
return 0;
}
I've checked that the necessary header files exist on Linux and that appears to be the case.
If I comment out the EOF check the console returns the message that
Process returned 49 (0x31)
A snippet of the import file which fails under Linux is:
1138,1139,1137.25,1138.5
1138.25,1138.75,1138.25,1138.5
1138.75,1139,1138.5,1138.75
1138.75,1138.75,1138.25,1138.25
1138.25,1138.25,1137.5,1137.5
1137.5,1138.75,1137.5,1138.5
1138.75,1143.75,1138.75,1143
1143.25,1145.75,1143.25,1144.5
1144.5,1144.75,1143,1143.25
1143.5,1144.5,1143.25,1144.25
Grateful for any help in finding a solution.
That return 4321; in main reports an unsuccessful return code to the OS. Only 0 return code (aka EXIT_SUCCESS) is considered successful.
Change it to return 0 or completely remove that return statement (in C++ main has implicit return 0).

vcl methods + exceptions corrupt memory with bcc64

My colleagues and I had a strange bug in a C++ Builder program and boiled it down to the following snippet:
#include <vcl.h>
#include <iostream>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw "abc";
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (...) {
}
std::cout << innocent << std::endl;
return 0;
}
Expected Output:
42
42
Actual Output when compiled for 64bit/ReleaseBuild/OptimizationsON:
42
1337
Compiler (latest 10.1 Berlin version of C++ Builder):
Embarcadero C++ 7.20 for Win64 Copyright (c) 2012-2016 Embarcadero Technologies, Inc.
Embarcadero Technologies Inc. bcc64 version 3.3.1 (35759.1709ea1.58602a0) (based on LLVM 3.3.1)
The internet says [citation needed] that the bug is always in the user program but never in the compiler or standard library, so please enlighten us if/where we do things that are not to be done in C++ / C++ Builder.
Strictly speaking, there is nothing wrong with this code, so it has to be a compiler bug. File a bug report at Quality Portal.
That being said, you should generally stay away from using catch (...). If you are going to catch an exception at all, at least catch what you are expecting and willing to handle:
catch (const char *)
Let anything unexpected pass through and be handled higher up the caller chain.
I would not recommend throwing a string literal directly. It is better to wrap it in a std::runtime_error or System::Sysutils::Exception based object instead.
#include <vcl.h>
#include <iostream>
#include <stdexcept>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw std::runtime_error("abc");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (const std::runtime_error &) {
}
std::cout << innocent << std::endl;
return 0;
}
#include <vcl.h>
#include <iostream>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw Exception("abc");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (const Exception &) {
}
std::cout << innocent << std::endl;
return 0;
}

error C4716: function : must return a value

So I am trying to use pthread libraries for Visual C++(2012) and I get this error error C4716: 'print_message' : must return a value
Here's the code
#include "stdafx.h"
#include <iostream>
#include "pthread.h"
using namespace std;
void* print_message(void *)
{
cout << "Threading\n";
}
int main()
{
pthread_t t1;
pthread_create(&t1, NULL, print_message, NULL);
cout << "Hello";
void* result;
pthread_join(t1,&result);
return 0;
}
Add return NULL; to print_message. I'll bet you need to name the argument too.

Memory problems message

I have a question about an error message that is displayed whenever I execute my C++ code, the error message is as follows:
Exception non gérée à 0x00839057 dans FirstReport1.exe : 0xC00000FD: Stack overflow.
1) what does this mean?
2) how can I avoid it and execute my code normaly?
the code i am executing is the following:
#include <iostream>
#include <fstream>
#include <ctime>
#include <iomanip>
using namespace std;
const int width(10001);
const int height(15);
void main()
{
ifstream inputfile ("file6.txt");
ofstream outputfile ("outfile.txt");
ofstream filteredfile ("filteredfile.txt");
ofstream timefile ("time.txt");
clock_t tstart, tend;
tstart = clock();
int i, x, y;
double tab[height][width];
for (y=0; y<height; y++){
for (x=0; x<width; x++){
tab[y][x]=0;
}
}
if (inputfile){
for (y=0; y<height; y++){
for (x=0; x<width; x++){
inputfile >> tab[y][x];
}
}
}
if (filteredfile){
for (y=0; y<height-1; y++){
for (x=0; x<width-1; x++){
if (tab[y+1][x+1]==-9999 || tab[y+1][x+1]<20 || tab[y+1]
[x+1]>1200) {tab[y+1][x+1]= 0;}
filteredfile << tab[y][x] << '\t';
}
}
}
tend = clock();
double time;
time = double (tend-tstart)/CLOCKS_PER_SEC;
timefile << time;
}
You're creating an array "tab" on the stack, which has 10001x15 elements. Each element is a double, which is 8 bytes in size. So the array is 1,200,120 bytes which may be larger than the default stack size. I recall this is 1MB in Visual c++.
Either put this array somewhere other than the stack, or increase your stack size.

Resources