File Buffer Size Too Small - c

I am trying to make a small program in C which reads in a file and calculates a CRC on the contents. I created the program in netbeans and in the IDE everything works. When I build the project with GCC and run the generated exe the program fails when reading in the file. The file is 1.3 Mb.
When reading in the file I eventually get the error "Internal error: TP_NUM_W_BUFS too small: 50"
My read code is fairly simple, it does very little line processing.
while (fgets(line, HEX_LINE_LENGTH, fp))
{
int len = strlen(line);
line[len] = line[len-1];
line[len-1] = '\r';
memcpy(&hex_lines[num_lines], line, HEX_LINE_LENGTH);
num_lines++;
printf("%s\n", line);
memset(line, 0, HEX_LINE_LENGTH);
}
I am seeing a new issue. When reading in my file via the netbeans IDE everything works fine. When I compile the program from a command line with
g++ main.c crc_calculator.c crc_calculator.h -o crc
I get a crc.exe file. Running this will read in my file but will report that twice as many lines have been read than actually exist.

Related

fgets() crashes in coreos

I have this C code snippet which runs on a coreOS machine:
char db[512];
snprintf(db, 512, "%s %s", <some command>, <args of the command>);
FILE* pipe = popen(db, "r");
if (!pipe) {
return NULL;
}
char buf[256];
while (fgets(buf, sizeof(buf), pipe) != NULL) {
<DEBUG POINT 1>
<some code utilising buf>
}
<DEBUG POINT 2>
Now the command that is being executed and which is streaming to the Pipe in eventually calling a python code which returns None(Null) with the given argument.
The problem that I'm facing is that fgets is not able to handle the response and the program crashes when it tries to execute fgets() on the Pipe. What I mean is that on reaching while(), my program exits and is not able to reach either DEBUG POINT 1 or 2. I have tried searching for possible solutions but am not able to find anything.
Another interesting thing is when I run the same code on a Amazon Linux Machine, it works fine and I get the desired behaviour.
Can someone please guide me in the right direction.

Segmentation Fault in Terminal but not on koding.com

I'm writing a C program, and it is dealing with fairly large files (~4MB .txt files). The program opens the big file and splits it up into a bunch of little files, before testing each of the little files. I've written a function that later opens those files, tests to make sure the full section was copied, and returns 1 if the section was not effectively copied (a different bug I'm having is that sometimes it only copies the first 2 words of a section). When I compile & run my program through koding.com (which uses the gcc compiler), it works perfectly for all test files. However, when I try to run it locally on my MacBook through Terminal (I run Lion, and have the version of gcc included in Xcode 4.6.3), it gives me "Segmentation fault: 11" and quits, but only when I use it on certain files (e.g. a 3.9MB file gives the segfault, but a 2.7MB file does not).
Here is how the function is called:
for(i=1;tableArray[i].count!=0;i++)
{
strcpy(word,tableArray[i].shortName);
strcat(word,".txt");
if(fopen(word, "r")!=NULL)
{
testFile = fopen(word, "r");
problems[i] = checkFile(testFile);
fclose(testFile);
}
}
And here is the function:
int checkFile(FILE *file)
{
char word[NAMELEN];
int count = 0;
while(fscanf(file, "%s", word)!=EOF)
count++;
if(count<3)
return(1);
else return(0);
}
Any insight is much appreciated. Thanks!

Trouble testing copy file function in C

Okay so this is probably has an easy solution, but after a bit of searching and testing I remain confused.. :(
Here is a snippet of the code that I have written:
int main(int argc, char *argv[]){
int test;
test = copyTheFile("test.txt", "testdir");
if(test == 1)
printf("something went wrong");
if(test == 0)
printf("copydone");
return 0;
}
int copyTheFile(char *sourcePath, char *destinationPath){
FILE *fin = fopen(sourcePath, "r");
FILE *fout = fopen(destinationPath, "w");
if(fin != NULL && fout != NULL){
char buffer[10000];//change to real size using stat()
size_t read, write;
while((read = fread(buffer, 1, sizeof(buffer), fin)) > 0){
write = fwrite(buffer, 1, read, fout);
if(write != read)
return 1;
}//end of while
}// end of if
else{
printf("Something wrong getting the file\n");
return 0;}
if(fin != NULL)
fclose(fin);
if(fout != NULL)
fclose(fout);
return 0;
}
Some quick notes: I am very new to C, programming, and especially file I/O. I looked up the man pages of fopen, fread, and fwrite. After looking at some example code I came up with this. I was trying to just copy a simple text file, and then place it in the destination folder specified by destinationPath.
The folder I want to place the text file into is called testdir, and the file I want to copy is called test.txt.
The arguments I have attempted to use in the copyFile function are:
"test.txt" "testdir"
".../Desktop/project/test.txt" ".../Desktop/project/testdir"
"/Desktop/project/test.txt" "/Desktop/project/testdir"
I just get the print statement "Something wrong getting the file" with every attempt. I am thinking that it may be because 'testdir' is a folder not a file, but then how would I copy to a folder?
Sorry if this a really basic question, I am just having trouble so any advice would be awesome!
Also, if you wanted to be extra helpful, the "copyTheFile" function is supposed to copy the file regardless of format. So like if its a .jpg or something it should copy it. Let me know if any of you guys see a problem with it.
This is with ISO/POSIX/C89/C99 on Linux.
At the start, you'll want to include stdio.h to provide FILE and the I/O function declarations:
#include <stdio.h>
Aside from this, your program compiles and works properly for me. Unfortunately you can't copy to a directory without using stat() to detect if the destination is a directory, and if so, appending a file name before opening the file.
Some other minor suggestions:
A buffer with a power of two bytes such as 4096 is probably more efficient due to it lining up with filesystem and disk access patterns
Conventionally, C functions that return a status code use 0 for success and other values such as 1 for failure, so swapping your return values may be less confusing
When a standard library function such as fopen, fread or fwrite fails, it is a good idea to use perror(NULL); or perror("error prefix"); to report it, which may look something like:
$ ./a.out
...
error prefix: No such file or directory
if you are trying to write a new file in a directory, you should be giving the full path of the file to be written. in your case
"C:...\Desktop\project\testdir\testfile"

C file IO extra characters when writing and reading from file

Ok so i am writing a C program. The program is simple enough, when i run the program i give it a few parameter Ex ./proj1 cat hat bat, so then it asks me to input a list of words the program gives counts of how many times "cat", "hat", and "bat" occurs in that list.
I have the program working great.
Example
./pro1 cat hat bat
cat
.
(the program recognized a "." as the end of input)
Result:
cat:1
hat:0
bat:0
ok so my program runs perfectly in every test case i can think of, but I have to pass a series of tests that my professor has mas made.
here is the code of that test.
char *args[] = {"./main", "cat", "hat","bat",NULL};
char *result[] = {"Looking for 3 words\n",
"Result:\n",
"cat:1\n",
"hat:0\n",
"bat:0\n"};
FILE *out;
FILE *test;
test=fopen("test","w");
int i;
char *buffer=malloc(100*sizeof(char));
out = fopen("smp0.in", "w");
fprintf(out, "cat\n");
fprintf(out, ".\n");
fclose(out);
freopen("smp0.in", "r", stdin);
freopen("smp0.out", "w", stdout);
quit_if(main(4, args) != EXIT_SUCCESS);
fclose(stdin);
fclose(stdout);
out = fopen("smp0.out", "r");
for (i = 0; i < 5; i++) {
quit_if(fgets(buffer, 100, out) == NULL);
quit_if(strcmp(buffer, result[i]));
}
fclose(out);
return EXIT_SUCCESS;
}
ok so sending the quit_if() is the method that makes it fail. specifically
quit_if(strcmp(buffer, result[i]));
My output when i run the program is exactly as described. But between freopen() diverting stdout to a file and then reading it back it has changed somehow.
Result:
cat:1
hat:0
batÿ:0
is what the output becomes, but it is not like that before the file write and read, and for some reason it is always that weird y character.
any advice would be greatly appreciated.
Sorry for not posting more code but it's because it is a school project.
I am confident that it is the test that is wrong in some way and not my code, fixing the test is part of the project as well.
See this answer to a previous question:
https://stackoverflow.com/a/4906442/2009431
It seems that when the dot is read back in from your stdin file, it has an EOF token appended (makes sense) that would not normally be part of the user's input. Then, somehow (not sure since we can't see your code) your main() function is appending that EOF character onto "bat" in the form of that weird y character (see linked answer for details on why).
If I'm right, maybe this could be considered a bug in the test?

Help with opening a file in C on Xcode

I'm trying to open a simple .rtf file called test in C. I'm using Xcode. My code is:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, const char * argv[]) {
FILE *filePtr;
filePtr = fopen("test.rtf", "r");
if (filePtr == NULL) {
fprintf(stderr, "Can't open \"test\"\n");
exit(EXIT_FAILURE);
}
else {
printf("File open successful\n");
int x;
/* read one character at a time until EOF is reached */
while ((x = fgetc(filePtr)) != EOF) {
printf("%c", x);
}
}
fclose(filePtr);
return 0;
}
I have the test.rtf file in the same directory as my Xcode.proj directory. My output is "File open successful", however I do not get anything read from the file. Am I doing this right? Thanks.
There's nothing wrong with that code at all. I tested it (albeit not in Xcode) with a file and the transcript was:
pax> echo hello >test.rtf
pax> ./qq.exe
File open successful
hello
So the obvious think to ask is what happens when you examine test.rtf? Does it actually have any content? Because, when I do:
pax> rm test.rtf ; touch test.rtf
pax> ./qq.exe
File open successful
I get the same behaviour you observe.
Also try renaming it to test2.rtf temporarily and make sure you get the error. It's possible it may be opening a different copy of the file than what you think (this often happens in Visual C since the directory the program runs in is not always what developers think at first).
It looks right.
As for the lack of output, two possibilities:
Are you sure the file has some content? Maybe ls -l test.rtf or dir test.rft
Possibly it has some control characters which cause the terminal to which it is written to suppress output.
Try moving test.rtf to your build directory. If your project is named MyProject, move it to MyProject/build/Debug/.
I can think of two things that could cause this problem. Either there is an error when calling fgetc, or you are getting output that you don't recognize.
fgetc() will return EOF when the end of the file is reached, or an error occurs. To determine if it's an error, just after your while loop try:
if (ferror(filePtr) != 0) printf("error: %d.\n", errno);
A .rtf file is not a plain text file. It likely contains a bunch of formatting information. You are expecting to see "Hello . . . ". but what you may actually see is something like:
{\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf250
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww9000\viewh8400\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040
\f0\fs24 \cf0 Hello . . .
And you are just assuming that is GDB output, not your program's output.
Based upon your recent comments, I think you have an empty file test.rtf in the directory your program is run in, and your real test.rtf file is in some other directory. Maybe your fopen() call at some point was fopen("test.rtf", "w"); instead of fopen("test.rtf", "r");, and you later modified it.
To see the directory your program is running in, add the following to your program after the FILE *filePtr; line:
char pwd[512];
if (getcwd(pwd, sizeof pwd) != -1)
printf("In directory %s\n", pwd);
else
fprintf(stderr, "Need bigger buffer, change '512' above\n");
Then, you can open a terminal, do cd <directory>, and test for yourself if the file you want is the file your program is opening.
You probably want this file to be plain text, not rich text. Rich text has a lot of formatting encoded into the file.

Resources