Inconsistent behaviour with fopen in C/C++ - c++

I'm working with a library which opens the same file many times. It checks the header of the file to make sure that it is the correct format. The first 1212 times it opens the file, it behaves correctly. The 1213th time, the bytes read out from the file are different. Can anyone suggest why this might be happening?
Unfortunately I can't make a small reproducible example - and it takes 20 minutes to run through to this point. So I'm wondering if there are any subtleties of fopen which I might have missed, or something else which might have a bearing on this execution.
The code is below. Many instances of the class are created, and each on has initialise() called with the same filename. The first 1212 times, the output is:
Expecting: '?'
?lon-1800????%#LYB1800????%#LYB100????%#LYB
lat-900??p-2?%#HYB900??p-2?%#HYB10??p-2?%#HYB
? soilcode0 ?? ?-2?&#AYB12 ?? ?-2?&#AYB1 ?? ?-2?&#AYBmtemp-600??x.2?&#6YB600??x.2?&#6YB10??x.2?&#6YB
?mprec0???H2?&#.YB99999???H2?&#.YB1999???H2?&#.YB?msun0???A2?&#%YB1000???A2?&#%YB100???A2?&#%YB
?
Got: '?'
?lon-1800????%#LYB1800????%#LYB100????%#LYB
lat-900??p-2?%#HYB900??p-2?%#HYB10??p-2?%#HYB
? soilcode0 ?? ?-2?&#AYB12 ?? ?-2?&#AYB1 ?? ?-2?&#AYBmtemp-600??x.2?&#6YB600??x.2?&#6YB10??x.2?&#6YB
?mprec0???H2?&#.YB99999???H2?&#.YB1999???H2?&#.YB?msun0???A2?&#%YB1000???A2?&#%YB100???A2?&#%YB
?
The last time I get:
Expecting: '?'
?lon-1800????%#LYB1800????%#LYB100????%#LYB
lat-900??p-2?%#HYB900??p-2?%#HYB10??p-2?%#HYB
? soilcode0 ?? ?-2?&#AYB12 ?? ?-2?&#AYB1 ?? ?-2?&#AYBmtemp-600??x.2?&#6YB600??x.2?&#6YB10??x.2?&#6YB
?mprec0???H2?&#.YB99999???H2?&#.YB1999???H2?&#.YB?msun0???A2?&#%YB1000???A2?&#%YB100???A2?&#%YB
?
Got: ' lon lat year
The function is as follows:
class Archive {
private:
FILE* pfile;
<snip>
bool initialise(char* filename) {
int i;
unsigned char* pheader;
if (pfile) fclose(pfile);
pfile=fopen(filename,"rb");
if (!pfile || pfile == NULL ) {
printf("Could not open %s for input\n",filename);
return false;
}
pheader=new unsigned char[CRU_1901_2002_HEADERSIZE-4];
if (!pheader) {
printf("Out of memory\n");
fclose(pfile);
pfile=NULL;
return false;
}
::rewind(pfile);
fread(pheader,CRU_1901_2002_HEADERSIZE-4,1,pfile);
printf( "Expecting: '%s'\n", CRU_1901_2002_HEADER);
for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
printf( "%c", CRU_1901_2002_HEADER[j]);
printf( "\nGot: '%s'\n", pheader);
for( int j = 0; j < CRU_1901_2002_HEADERSIZE-4;j++ )
printf( "%c", pheader[j]);
printf( "\n");
for (i=0;i<CRU_1901_2002_HEADERSIZE-4;i++) {
if (pheader[i]!=CRU_1901_2002_HEADER[i]) {
fclose(pfile);
pfile=NULL;
delete pheader;
return false;
}
}
delete pheader;
::rewind(pfile);
fseek(pfile,CRU_1901_2002_HEADERSIZE+CRU_1901_2002_DATA_LENGTH*CRU_1901_2002_NRECORD,SEEK_CUR);
recno=0;
iseof=false;
return true;
}
public:
Archive() {
pfile=NULL;
}
Archive() {
if (pfile) fclose(pfile);
}

Are you sure that there is data in the 1213th position? or, are these data are correct?
I suggest you mount a file with more than 1213th records and do a test to confirm if there is a read error or not in this position.

It turns out this is down to too many files being open. Changing the program elsewhere to open less files fixes it.
Checking fread returns 1, except for the last one, where it returns 0.
However, I don't understand why fopen gives back a non-null file pointer when it can't open the file. In test code, it returns NULL, which is then caught as expected.

Related

Knowing where is the segmentation fault happening comparing two files

I have the following structure:
int main(int argc, char **argv) {
try {
FX3USBConnection fx3USB3Connection = FX3USB3Connection();
fx3USB3Connection.send_text_file();
}
catch (ErrorOpeningLib& e) {
printf("Error opening library\n");
return -1;
}
catch (NoDeviceFound& e) {
printf("No device found\n");
return 0;
}
return 0;
}
Within send_text_files, the last thing I do is compare two txt files as follows:
printf("Loopback recieved, checking if I received the same that I sended\n");
files_match(out_text_filename, in_text_filename);
printf("Exited without problem");
return; // (actually implicit)
I already used 2 version of files_match function but the last one is an exact copy of this Compare two files
bool FX3USB3Connection::files_match(const std::string &p1, const std::string &p2) {
bool files_match;
std::ifstream f1(p1, std::ifstream::binary|std::ifstream::ate);
std::ifstream f2(p2, std::ifstream::binary|std::ifstream::ate);
if (f1.fail() || f2.fail()) {
return false; //file problem
}
if (f1.tellg() != f2.tellg()) {
return false; //size mismatch
}
//seek back to beginning and use std::equal to compare contents
f1.seekg(0, std::ifstream::beg);
f2.seekg(0, std::ifstream::beg);
files_match = std::equal(std::istreambuf_iterator<char>(f1.rdbuf()),
std::istreambuf_iterator<char>(),
std::istreambuf_iterator<char>(f2.rdbuf()));
f1.close();
f2.close();
if (files_match) { printf("Files match\n"); }
else { printf("Files not equal\n"); }
return files_match;
}
Sometimes I get an error and sometimes I don't. When I get the error I get:
Loopback recieved, checking if I received the same that I sended
Files match
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
So, the print after the call to files_match is not being print so I guess the problem was within the function. However, I do a print just before the return statement and it is printing correctly.
PS: I commented the function files_match and I have no problems.
PS1: The files can have whatever like this character: ¥
Yes, as #john suggested, I had to add the fflush() function. There I realize the error was actually outside all this loop but actually is when getting out of the try{} section. It seams to me that is not managing to destroy the fx3USBConnection.
Thank you! I was so mislead now knowing fprint was actually buffered.

Communication with Arduino using Linux

This is the first time I'm communicating with Arduino using my computer. I use Ubuntu 14.04. This is the C program for writing to the file. The Arduino shows up ttyACM0.
While compiling using gcc the compiler shows an error saying:
Segmentation fault(core dumped)
How do I rectify this error.
#include<unistd.h>
#include<stdio.h>
int main() {
char data[] = {'f','b','r'}; //Random data we want to send
FILE *file;
file = fopen("/dev/ttyACM0","w"); //Opening device file
int i = 0;
for(i = 0 ; i < 3 ; i++) {
fprintf(file,"%c",data[i]); //Writing to the file
fprintf(file,"%c",','); //To separate digits
sleep(1);
}
fclose(file);
}
Pardon my ignorance. I tried researching on it. Couldn't make it work. Thanks in advance for your help.
You're getting a NULL return from the fopen() that NULL is being passed to fprintf() which is expecting a valid FILE* and messing up causing the SEGV.
If you use fopen you should check what it returns so you can give the user a something more useful than "segmentation fault".
The probable cause of the fopen() failure is you don't have permission to play with the serial port.
Normally you need the group dialout to be able to access the serial port.
As root do:
usermod -a -G dialoutyourusername
Then log out and back in so you get the new group.
Consider using minicom or microcom (on any of the several other serial terminal programs) to access the serial port instead of writing your own.
I also suggest you have the Arduino send a hello message when it boots up so you can be sure you have the right baud rate etc...
You did not put any success check on the return value of fopen("/dev/ttyACM0","w");. In case fopen() fails, using file further is undefined behavior, causing segmentation fault. Do something like
file = fopen("/dev/ttyACM0","w"); //Opening device file
if (file)
{
//do something with file
}
else
return 0;
Also, add a return 0 before ending main().
// the following code:
// compiles cleanly
// performs appropriate error checking
// has proper return statement
#include <unistd.h> // sleep()
#include <stdio.h> // fopen(), fclose(), fprintf(), perror()
#include <stdlib.h> // exit() and EXIT_FAILURE
int main()
{
char data[] = {'f','b','r'}; //Random data we want to send
FILE *file;
if( NULL == (file = fopen("/dev/ttyACM0","w") ) ) //Opening device file
{ // then fopen failed
perror("fopen failed for ttyACM0" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
int i = 0;
for(i = 0 ; i < 3 ; i++)
{
if( 0 >= fprintf(file,"%c",data[i]) ) //Writing to the file
{ // fprintf failed
perror("fprintf data failed" );
exit( EXIT_FAILURE );
}
// implied else, fprintf successful for data
if( 0 >= fprintf(file,"%c",',') ) //To separate digits
{ // then, fprintf failed
perror( "fprintf for comma failed");
exit( EXIT_FAILURE );
}
// implied else, fprintf successful for comma
sleep(1);
} // end for
fclose(file);
return(0);
} // end function: main
On failure fopen returns NULL, so you are potentially dereferencing a NULL pointer, the correct way of doing that, is checking the result of fopen. I would however suggest low level IO for this kind of thing something like
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main()
{
char data[] = {'f','b','r'}; //Random data we want to send
int fd;
int i;
fd = open("/dev/ttyACM0", O_WRONLY); //Opening device file
if (fd == -1)
{
perror("cannot open /dev/ttyACM0");
return -1;
}
for(i = 0 ; i < 3 ; i++)
{
write(fd, &(data[i]), 1);
write(fd, ",", 1);
sleep(1);
}
close(fd);
return 0;
}
on error open returns a special value -1 so you should abort writing to it.
I'm pretty sure in your case there will be a permission denied error, since normally the /dev/tty* belong to group dialout and they have group write permission by default, but since probably your user doesn't belong to that group you don't have write access to /dev/ttyACM0.

receiving webpages using windows sockets(C ++),but got some unexpected words

I am trying to get a webpage with sockets,using http GET.I do get the page,but there is something little wrong.
Sometimes I got it all right,but sometimes I got it with wrong characters like:
**<td class="c_ba2636">09</t
1ff8
d>**
it should be :
<td class="c_ba2636">09</td>
I donot know why there is a "1ff8" and some "\r\n".
It happens here and there from time to time.And sometimes it occurs like:
06
again it should be :
<td class="c_ba2636">06</td>
this is how I receive and save the page from a socket:
ofstream out("webpage.html");
char text[2050]="";
int recvbytes=0;
string content;
while ( (recvbytes = recv(sock, text, 2048, 0)) > 0)
{
content=string(text,recvbytes);
out << content.c_str();
//System::Console::Write(gcnew String(content.c_str()));
}
closesocket(sock);
out.close();
I tried :out << text; it did not work.
Please does anyone know what's wrong with my codes.
I am using VS2010,and this is a winform program.
It may be normal if your input text is UTF8 encoded and contains characters out of ASCII space
Now I got it done.it turns out that those "1ff8" "2000" or whatever are from some http protocols,to indicates something(length?).I just need to delete those lines and rearrange the lines that are interrupted by them.So I add a function:
private: void rearrangment()
{
ifstream ifile("webpage.html");
ofstream ofile("web.html");
char line1[2048]="";
char line2[2048]="";
char line3[2048]="";
ifile.getline(line1,2047);
//ifile.getline(line2,2047);
while(!ifile.eof())
{
ifile.getline(line2,2047);
if(string(line2,0,3)!=" "
&& line2[0]!='<' && line2[1]!='<' && line2[2]!='<')//they are "1ff8"s
{
ifile.getline(line3,2047);
for(int i=0;i<2046;++i)
{
if(line1[i]==13)
{
line1[i]=0;
break;
}
}
strcat(line1,line3);
}
else
{
ofile<<line1<<endl;
strcpy(line1,line2);
//ofile<<line1;
}
//ofile<<line1;
}
ifile.close();
ofile.close();
}
and now it works well.
Sorry about this stupid question,I should have searched before I asked.

Permission Denied when I use remove()

I have this issue. I have a C++ program; the program successfully make files in which I save records. In one procedure I edit one record and make another file with different name. At the end I close the both files and when I try to delete old one and rename the new one I have this error:
Error deleting file: Permission denied.
void SoldDevices()
{
int soldQuantity = 0;
char soldModel[20];
ElShop tempVar;
FILE *newFile;
printf("Enter model of sold device: ");
gets(soldModel);
file = fopen(fileName, "r+");
fread(&shop, sizeof(shop), 1, file);
while (!feof(file))
{
if (strcmp(shop.model, soldModel) == 0)
{
tempVar = shop;
break;
}
fread(&shop, sizeof(shop), 1, file);
}
fclose(file);
printf("Enter how much devices are sold: ");
scanf("%d", &soldQuantity);
while (tempVar.quantity < soldQuantity)
{
printf("No items available!\n");
printf("Enter how much devices are sold: ");
scanf("%d", &soldQuantity);
}
tempVar.quantity = tempVar.quantity - soldQuantity;
printf("%d\n", tempVar.quantity);
file = fopen(fileName, "rb");
newFile = fopen("New", "wb");
fread(&shop, sizeof(shop), 1, file);
while (!feof(file))
{
if(strcmp(soldModel, shop.model) == 0)
{
fwrite(&tempVar, sizeof(shop), 1, newFile);
}
else
{
fwrite(&shop, sizeof(shop), 1, newFile);
}
fread(&shop, sizeof(shop), 1, file);
}
fclose(newFile);
fclose(file);
if( remove( fileName ) != 0 )
perror( "Error deleting file" );
else
puts( "File successfully deleted" );
rename("New", fileName);
}
Did anyone have some ideas to resolve the problem?
I once had the same problem like you, but now I had solved it.
You must had some file-pointers that haven't closed when you used remove(). It does not have to be in the same .cpp file, maybe in different files.
Take me as an example, I think I had closed the file, but later I found out that I have "return" sentences before fclose() which results in the file not being closed correctly.
PS:
1. I have 3 .cpp files.
The file containing remove() was used after the file(A.cpp) that didn't make the file closed correctly.
Because the A.cpp don't closed the file correctly so that the Permission Denied appears.
My English is poor. Hope this can help you.

Ofstream not writing to file C++

I have this method which supposed to get a buffer and write some content to a file:
void writeTasksToDevice()
{
TaskInfo *task;
unsigned int i = lastTaskWritten;
printf("writing elihsa\n");
outputFile.write(" Elisha2", 7);
//pthread_mutex_lock(&fileMutex);
for(; i < (*writingTasks).size(); i++)
{
task = (*writingTasks).at(i);
if(NULL == task)
{
printf("ERROR!!! in writeTasksToDevice - there's a null task in taskQueue. By "
" design that should NEVER happen\n");
exit(-1);
}
if(true == task->wasItWritten)
{
//continue;
}
else // we've found a task to write!
{
printf("trying to write buffer to file\n");
printf("buffer = %s, length = %d\n", task->buffer, task->length);<====PRINT HERE IS OK< PRINTING WHAT IS WANTED
outputFile.write(task->buffer, task->length); <===SHOULD WRITE HERE
printf("done writing file\n");
}
}
//pthread_mutex_unlock(&fileMutex);
// TODO: check if we should go to sleep and wait for new tasks
// and then go to sleep
}
the buffer content is:
task->buffer: elishaefla
task->length: 10
i opened the stream in another init function using:
outputFile.open(fileName, ios :: app);
if(NULL == outputFile)
{
//print error;
return -1;
}
but at the end, the file content is empty, nothing is being written.
any idea why?
You did not provide enough information to answer the question with certainty, but here are some of the issues you might be facing:
You did not flush the buffer of the ofstream
You did not close the file that you are trying to open later on (if I'm correct, outputFile is a global variable, so it is not closed automatically until the end of the program)