I'm getting that error by running this simplest code:
#include "stdio.h"
#include "stdlib.h"
int main()
{
FILE* in;
FILE* out;
in = fopen("foo.in", "r");
out = fopen("bar.out", "w+");
int something;
fscanf(in, "%i", something);
fprintf(out, "%i", something);
fclose(in);
fclose(out);
return 0;
}
I'm running it out of Sublime Text 3.
fscanf expects a pointer, meaning that it modify the value of something while in the function fscanf if you send it by copy the value will be correct while in scope (i.e. while in fscanf) but the result is never returned so your copy of something is never changes, (i.e. it's still not initialized).
so what you need to do:
int something;
fscanf(in, "%i", &something);
fprintf(out, "%i", something);
and it should work, if you are trying to read an integer from foo.in and write it to bar.out.
Related
I'm making a very simple program to read in from a text file and print the contents. When the file finishes compiling I keep getting this debug assertion failed message!
I've never seen it before and can't seem to find any solutions.
(It won't let me post an image because my rep isn't high enough!)
The code
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *file = fopen("C:\\Users\Kyne\\Desktop\\AdvProgrammingAssignment\\employees.txt", "r");
char c;
do
{
c = fgetc(file);
printf("%c", c);
}
while(c != EOF);
fclose(file);
return 0;
printf("\n\n\n");
system("pause");
}
Step through your code using the debugger to find the line that is causing the debug assertion, and check to see if the file is opened.
In the line
FILE *file = fopen("C:\\Users\Kyne\\Desktop\\AdvProgrammingAssignment\\employees.txt", "r");
it looks like you missed a '\' before 'Kyne' so it should be
FILE *file = fopen("C:\\Users\\Kyne\\Desktop\\AdvProgrammingAssignment\\employees.txt", "r");
There are other issues like calling return 0; before the end of the main block.
I don't see any checks if file was opened properly. Also, I would check for EOF mark before first read - use while and feof() instead. Finally, these lines:
printf("\n\n\n");
system("pause");
will never get called, as you do return 0 after fclose() - move it [return 0] to the end.
Try this:
int main()
{
FILE *file = fopen("C:\\Users\\Kyne\\Desktop\\AdvProgrammingAssignment\\employees.txt", "r");
if(!file)
{
printf("File could not be opened!\n");
return -1;
}
while(!feof(file))
{
char c = fgetc(file);
printf("%c", c);
}
fclose(file);
printf("\n\n\n");
system("pause");
return 0;
}
Most likely, your error originated in using FILE* set to NULL - you have one slash missing after \\Users, so file probably was never opened and fopen() was constantly returning NULL.
I am running the following program below. I am taking the first 63 char values in B.txt and then attaching the float values in A.txt, beginning at the 62nd column in A.txt, at the end of the lines of B.txt
So if B.txt contains:
I am running the following program below. I am taking the firstXXXXXXXX
and A.txt contains:
I am running the following program below. I am taking the fir3.14
I want B.txt to look like:
I am running the following program below. I am taking the first3.14
However, the output I'm getting instead is:
I am running the following program below. I am taking the firstBUNCH OF JUNK3.14
int main()
{
loadfileB("B.txt");
return 0;
}
void loadfileB(char* fileName)
{
FILE* fp = fopen(fileName, "r");
char line[82];
vector<int> rownum;
vector<float> temp;
temp = loadfileA("A.txt");
int i = 0;
ofstream fout("output.txt");
while (fgets(line, 81, fp) != 0)
{
radius=temp[i];
char buffer[64];
strncpy(buffer, line, 63);
fout << buffer<< " " << radius << endl;
i++;
}
fclose(fp);
}
vector<float> loadfileA(char* fileName)
{
FILE* fp = fopen(fileName, "r");
char line[82];
vector<int> rownum;
vector <float> tempvec;
int i = 0;
while (fgets(line, 81, fp) != 0)
{
float temp;
getFloat(line, &temp, 60, 6);
tempvec.push_back(temp);
}
fclose(fp);
return tempvec;
}
void getFloat(char* line, float* d, int pos, int len)
{
char buffer[80];
*d = -1;
strncpy(buffer, &line[pos], len);
buffer[len] = '\0';
sscanf(buffer, "%f", d);
}
strncpy is a bad function to use. This is because it does not null-terminate its output if the input did not fit in the buffer. The garbage you are seeing is the result of passing a non-null-terminated buffer to a function that expected a null-terminated string.
The simplest fix is to replace:
char buffer[64];
strncpy(buffer, line, 63);
with:
std::string buffer = line;
buffer.resize(63);
In your other usage you do null-terminate, however you never check that len is smaller than 80 either. Again the simpler fix would be:
std::string buffer( line + pos, len );
sscanf(buffer.c_str(), "%f", d);
The getFloat function should have some way of signaling error (either a return value; or throw an exception if sscanf does not return 1).
Of course, you could replace a lot of your other C-style code with C++-style code too and avoid buffer size issues entirely.
Noobie Alert.
Ugh. I'm having some real trouble getting some basic file I/O stuff done using <stdio.h> or <fstream>. They both seem so clunky and non-intuitive to use. I mean, why couldn't C++ just provide a way to get a char* pointer to the first char in the file? That's all I'd ever want.
I'm doing Project Euler Question 13 and need to play with 50-digit numbers. I have the 150 numbers stored in the file 13.txt and I'm trying to create a 150x50 array so I can play with the digits of each number directly. But I'm having tons of trouble. I've tried using the C++ <fstream> library and recently straight <stdio.h> to get it done, but something must not be clicking for me. Here's what I have;
#include <iostream>
#include <stdio.h>
int main() {
const unsigned N = 100;
const unsigned D = 50;
unsigned short nums[N][D];
FILE* f = fopen("13.txt", "r");
//error-checking for NULL return
unsigned short *d_ptr = &nums[0][0];
int c = 0;
while ((c = fgetc(f)) != EOF) {
if (c == '\n' || c == '\t' || c == ' ') {
continue;
}
*d_ptr = (short)(c-0x30);
++d_ptr;
}
fclose(f);
//do stuff
return 0;
}
Can someone offer some advice? Perhaps a C++ guy on which I/O library they prefer?
Here's a nice efficient solution (but doesn't work with pipes):
std::vector<char> content;
FILE* f = fopen("13.txt", "r");
// error-checking goes here
fseek(f, 0, SEEK_END);
content.resize(ftell(f));
fseek(f, 0, SEEK_BEGIN);
fread(&content[0], 1, content.size(), f);
fclose(f);
Here's another:
std::vector<char> content;
struct stat fileinfo;
stat("13.txt", &fileinfo);
// error-checking goes here
content.resize(fileinfo.st_size);
FILE* f = fopen("13.txt", "r");
// error-checking goes here
fread(&content[0], 1, content.size(), f);
// error-checking goes here
fclose(f);
I would use an fstream. The one problem you have is that you obviously can't fit the numbers in the file into any of C++'s native numeric types (double, long long, etc.)
Reading them into strings is pretty easy though:
std::fstream in("13.txt");
std::vector<std::string> numbers((std::istream_iterator<std::string>(in)),
std::istream_iterator<std::string>());
That will read in each number into a string, so the number that was on the first line will be in numbers[0], the second line in numbers[1], and so on.
If you really want to do the job in C, it can still be quite a lot easier than what you have above:
char *dupe(char const *in) {
char *ret;
if (NULL != (ret=malloc(strlen(in)+1))
strcpy(ret, in);
return ret;
}
// read the data:
char buffer[256];
char *strings[256];
size_t pos = 0;
while (fgets(buffer, sizeof(buffer), stdin)
strings[pos++] = dupe(buffer);
Rather than reading the one hundred 50 digit numbers from a file, why not read them directly in from a character constant?
You could start your code out with:
static const char numbers[] =
"37107287533902102798797998220837590246510135740250"
"46376937677490009712648124896970078050417018260538"...
With a semicolon at the last line.
Is there any way to create a memory buffer as a FILE*. In TiXml it can print the xml to a FILE* but i cant seem to make it print to a memory buffer.
There is a POSIX way to use memory as a FILE descriptor: fmemopen or open_memstream, depending on the semantics you want: Difference between fmemopen and open_memstream
I guess the proper answer is that by Kevin. But here is a hack to do it with FILE *. Note that if the buffer size (here 100000) is too small then you lose data, as it is written out when the buffer is flushed. Also, if the program calls fflush() you lose the data.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *f = fopen("/dev/null", "w");
int i;
int written = 0;
char *buf = malloc(100000);
setbuffer(f, buf, 100000);
for (i = 0; i < 1000; i++)
{
written += fprintf(f, "Number %d\n", i);
}
for (i = 0; i < written; i++) {
printf("%c", buf[i]);
}
}
fmemopen can create FILE from buffer, does it make any sense to you?
I wrote a simple example how i would create an in-memory FILE:
#include <unistd.h>
#include <stdio.h>
int main(){
int p[2]; pipe(p); FILE *f = fdopen( p[1], "w" );
if( !fork() ){
fprintf( f, "working" );
return 0;
}
fclose(f); close(p[1]);
char buff[100]; int len;
while( (len=read(p[0], buff, 100))>0 )
printf(" from child: '%*s'", len, buff );
puts("");
}
C++ basic_streambuf inheritance
In C++, you should avoid FILE* if you can.
Using only the C++ stdlib, it is possible to make a single interface that transparently uses file or memory IO.
This uses techniques mentioned at: Setting the internal buffer used by a standard stream (pubsetbuf)
#include <cassert>
#include <cstring>
#include <fstream>
#include <iostream>
#include <ostream>
#include <sstream>
/* This can write either to files or memory. */
void write(std::ostream& os) {
os << "abc";
}
template <typename char_type>
struct ostreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> > {
ostreambuf(char_type* buffer, std::streamsize bufferLength) {
this->setp(buffer, buffer + bufferLength);
}
};
int main() {
/* To memory, in our own externally supplied buffer. */
{
char c[3];
ostreambuf<char> buf(c, sizeof(c));
std::ostream s(&buf);
write(s);
assert(memcmp(c, "abc", sizeof(c)) == 0);
}
/* To memory, but in a hidden buffer. */
{
std::stringstream s;
write(s);
assert(s.str() == "abc");
}
/* To file. */
{
std::ofstream s("a.tmp");
write(s);
s.close();
}
/* I think this is implementation defined.
* pusetbuf calls basic_filebuf::setbuf(). */
{
char c[3];
std::ofstream s;
s.rdbuf()->pubsetbuf(c, sizeof c);
write(s);
s.close();
//assert(memcmp(c, "abc", sizeof(c)) == 0);
}
}
Unfortunately, it does not seem possible to interchange FILE* and fstream: Getting a FILE* from a std::fstream
You could use the CStr method of TiXMLPrinter which the documentation states:
The TiXmlPrinter is useful when you
need to:
Print to memory (especially in non-STL mode)
Control formatting (line endings, etc.)
https://github.com/Snaipe/fmem is a wrapper for different platform/version specific implementations of memory streams
It tries in sequence the following implementations:
open_memstream.
fopencookie, with growing dynamic buffer.
funopen, with growing dynamic buffer.
WinAPI temporary memory-backed file.
When no other mean is available, fmem falls back to tmpfile()
Is there a function for FILE (fopen?) that allows me to just read one int from a binary file?
So far I'm trying this, but I'm getting some kind of error I can't see cause the program just crashes without telling me.
void opentest()
{
FILE *fp = fopen("dqmapt.mp", "r");
int i = 0;
int j = 0;
int k = 0;
int * buffer;
if (fp)
{
buffer = (int *) (sizeof(int));
i = (int) fread(buffer,1, (sizeof(int)), fp);
fscanf(fp, "%d", &j);
fclose(fp);
}
printf("%d\n", i);
printf("%d\n", j);
}
Now that you have changed your question, let me ask one. What is the format of the file you are trying to read?
For a binary file there are some changes required how you open the file:
/* C way */
FILE *fp = fopen("text.bin", "rb"); /* note the b; this is a compound mode */
/* C++ way */
std::ifstream ifs("test.txt", ios::in | ios::binary);
Reading in the contents is easy. But remember, your file has 2 integers at the begining -- width, height which determine how many more to read i.e. another width * height number of integers. So, your best bet is to read the first two integers first. You will need to use two buffers -- one for the width and height and then depending on their value another one to read the rest of the file. So, lets read in the first two integers:
char buf[ 2 * sizeof(int) ]; /* will store width and height */
Read in the two integers:
/* C way */
fread(buf, sizeof(int), 2, fp); /* the syntax changes, FILE pointer is last */
/* C++ way*/
ifs.read(buf, sizeof buf);
Now, the tricky part. You have to convert the stuff to double. This again depends on your system endianness -- whether a simple assignment works or whether a byte swapping is necessary. As another poster has pointed out WriteInt() writes integers in big-endian format. Figure out what system you are on. And then you can proceed further.
FILE is a C datastructure. It is included in C++ for C compatibility. You can do this:
/* The C way */
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *fp = fopen("test.txt", "r");
int i = 0;
if (fp) {
fscanf(fp, "%d", &i);
fclose(fp);
}
printf("%d\n", i);
}
You can use the std::ifstream thing to open a file for reading. You have to read in the contents using some other incantation to read the file contents and extract the desired information out of it yourself.
/* The C++ way */
#include <fstream>
#include <iostream>
int main() {
std::ifstream ifs("test.txt");
int i = 0;
if (ifs.good()) {
ifs >> i;
}
std::cout << i << std::endl;
}
Note you can use the C style functions in C++ as well, though this is the least recommended way:
/* The C way in C++ */
#include <cstdio>
#include <cstdlib>
int main() {
using namespace std;
FILE *fp = fopen("test.txt", "r");
int i = 0;
if (fp) {
fscanf(fp, "%d", &i);
fclose(fp);
}
printf("%d\n", i);
}
[Note: Both examples assume you have a text file to read from]
Do you want to read a textual representation of an int? Then you can use fscanf, it's sort of the opposite of printf
int n;
if( fscanf(filePointer, "%d", &n) == 1 )
// do stuff with n
If you want to read some binary data and treat it as an int, well that's going to depend how it was written in the first place.
I am not a Java programmer, so this is just based on what I've read in the [docs](http://java.sun.com/j2se/1.4.2/docs/api/java/io/DataOutputStream.html#writeInt(int)).
That said, it says
Writes an int to the underlying output stream as four bytes, high byte first. If no exception is thrown, the counter written is incremented by 4.
So it's a big endian four byte integer. I don't know if it's two's complement or not, but that's probably a safe assumption (and can probably be found somewhere in the java docs/spec). Big endian is the same as network byte order, so you can use ntohl to convert it the endianness of your C++ platform. Beyond that, you just need to read the four bytes, which can be done with fread.
Int represented as text or binary?
For text, use fscanf; for binary, use fread.