Problem with C program
This is a problem im doing for the ctutorial questions. It asked me to write a program that takes input from the user and removes all the spaces and replaces them with newlines. I did this to solve the problem but im getting one issue.
It displayes the error "Error Reading file for input" this is the error i told it to put if the open command return with a null. problem is with the this part "temp = fopen ("temp.str","w");" in theory acording to my tutorial this should find the file if it exists remove its contents and open it for writeing. problem is thats not what is occuring. its just apending the file not removing the current contents. even if the file does not exist i still get the message. mentiond above when trying to read the file. all and all the program works correctly ? so do i just need to abandon my quest with high level file routines and go low level or am i doing something wrong ? here is the code Code:
/* program takes input from user and strips */ |
What's the getline() function?
|
Quote:
Quote:
But why are you writing the input to a file and then read it back in? Once the input from the user is read into the buffer (the char *typed is the buffer) you can parse it for spaces from that buffer! Why first writing it to a file and then reading it into another buffer before parsing it? The getline() function is an advanced version of fgets(), and does some memory-fiddling if the buffer is not large enough to hold the data read. You are not using or checking for this, and I think you don't understand what its memory-fiddling feature is about (you have a mistake in your code caused by this, see comment below). Also getline() is a GNU-only function (it's not a commonly used function), which means your program will not compiled and run correctly on UNIX-like OS's that have not the GNU libc installed. In other words: it's not portable. I'd recommend fgets() instead of getline(), unless you have special reasons (which you don't in this case). One more thing: When you compile with "-Wall" you get all compiler warnings. This will give you more clues about mistakes. Code:
/* |
Yea seams to me im not totaly grasping the whole sizeof thing yet. Im just learning c and this is the first problem that was semi advanced that i have tried to tackle. The tutorial praises getline that is why i tried to use it instead of other methods. It doesent even mention fgets.
as for why i did not use the buffer im still a little in the fog on buffers. And file postion. I figured i would need to make a file because im using file postion to determine where the next word typed is. Is there a better way to replace a character in a string of undetermined length rather then the model that i have created ?? |
And remove the casts of malloc()'s return value:
Code:
typed = (char *) malloc (SIZE); Code:
typed = malloc (SIZE); I wonder why people insist on casting...must be alot of crappy tutorials out there. I know you have to cast in C++ but in C++ you should use new/delete because malloc/free doesn't understand constructors. |
Yea stupid tutorial never even explained what the (char * ) even was just that it needed to be in front of malloc.
I dident see why i needed to put it there either ??? |
The header and the ; in front of the if statement was my own bad :P and i think i tracked my less on the file problem down. Its less thats messed up not my data file that was created :P
STUPID LESS BUFFER !! |
Quote:
Code:
int main() Quote:
Quote:
Code:
void striprint(char *typed) |
Quote:
"Man malloc" or "grep malloc /usr/include/stdlib.h" will show you that malloc returns a void*, so it must be casted to the destination pointer type, unless it is a void*. Not doing it will trigger a C compiler warning. |
Quote:
Code:
itsme@dreams:~/C$ cat nowarn.c |
LOL this is so much eazier
Code:
void striprint(char *typed) silly me forgetting strings are arrays :tisk: |
Or you could just do it on-the-fly while printing the output:
Code:
{ |
Actually theres a problem with doing this way. What happens is because the size of the buffer is 100 it asumes the string is 100 so it loops untill it gets to 100 rather then stopping at the end of the input. Maybe this is why i dident do it this way?
|
upon setting malloc to 1 i get some very strange results.
|
never mind i wasent minding wehre the } are
it seams to work ok but i wonder if you make malloc too big would it continue to loop untill it got to 100 |
Never mind forgot getline sets the EOF at the end of the input no matter what SIZE is set to so even if it does loop 100 times printf will still only print out the data contained in the string.
Wow answering my own questions now |
Quote:
itsme86's code handles this right. So a "patched" version of mine then: Code:
void striprint(char *typed) |
This is the way I'd do it:
Code:
#include <stdio.h> Code:
itsme@dreams:~/C$ ./nl Code:
itsme@dreams:~/C$ ./nlbad |
As i mentioned before nothig was wrong with it i just wasent thinking clearly :)
Also checked the Tutorial on fgets and it was there it was listed under a depreciated function. |
Oops,..
I stand corrected. |
Quote:
gets() is wrong. fgets() is OK. |
TRY a null character on this program of yours and see if it breaks fgets supposedly this is why fgets is not supposed to be used anymore.
|
Quote:
EDIT: After some research, it seems that only crasseux.com seems to dog on fgets. And yeah, fgets() will store a null byte in the string if the user enters one somehow, but I don't see how that in any way can be dangerous. It will just cut the string off short. fgets() will work with any compiler and getline() won't, since it's not a standard function. There's not really any problem with fgets() anyway. In fact, an argument can be made that getline() is the buggy function since it's not accurately reading input. It fails to copy null bytes from the input and fgets() doesn't have that problem. Anyway, I don't know who these crasseux.com people are, but I wouldn't listen to them too much. |
Tried it.
Doesn't break. |
Okay, look at this:
Code:
itsme@dreams:~/C$ cat badfgets.c Code:
itsme@dreams:~/C$ ./badfgets Code:
itsme@dreams:~/C$ cat slimy.txt |
..and getline() won't do any different.
|
This is getting fustrating with c programming tutorials. Why does everyone has a diffrent idea on what is right and wrong. Not that im angry at you im not i greatly apreciate your help its these tutorials everyone has THERE way of learning. This is the the best one i can find thats why im trying to learn it. Why cant the authors stick to facts and keep there option out of a so called traning manual.
By the way if i can NOT use getline anywhere I would be estatic not to. It does seam buggy and harder to do some simple things. thanks guys |
C is not an easy programming language, it's a low-level programming language. Arguably the second lowest-level one (assembly being the lowest).
In C you need to take care of a lot of memory-handling/fiddling yourself. For non-trivial program this can become difficult and is the most common cause of bugs in even quite mature C-programs (buffer overflow security holes, memory leaks,..). Also these kind of bugs are known for being hard to track down. Even in your simple program this problem with memory-handling in C (buffer malloc's and such) appears. It can be done easier, but then there is a limit to the buffer size. And you need to make sure that the buffer will not be written to past the end of the buffer (same for reading, but that is not as harmful as writing), no matter what weird input the user feeds the program. You can make the buffer fixed-size and use fgets(). But what if the buffer is fixed at 100 bytes, and the user enters 2000? To be on the safe side, you may think of making the buffer 10000 bytes big. But then again, what if the user enters 15000 characters? Well you can make a HUGE buffer of 10 Mb. But now your program uses quite a lot of memory, while your user may only enter 10 characters. For your simple program this is not a real problem, but the same problem applies to software like web/ftp/mailservers, browser, etc. which need many more buffers of different sizes. Just making all buffers huge, in order to be able to store all expected data, is not the solution, because you'd need a lot of memory, just to run apache. If there is enough memory just run apache, then you may have a problem running another program with huge buffers at the same time. Getline() is a solution to this (for a small part). It enables the buffer to grow automatically if the data does not fit. This seams handy for newbies to C: If used in the right way you can read huge and small user-inputs without thinking about the memory buffer stuff. But it also can introduce problems when not used in the right way. These problems will be more difficult to understand for a newbie. I guess authors of tutorials (and other people) have to deal with the memory-issue of C almost from the start. So they think of solutions, or ways to get around it in teaching C to newbie's, like using getline() for example. It wouldn't be my choice, but I'm not a teacher. It's a matter of taste, I suppose. If you do not want to deal with this memory thing of C, you can choose a different (high-level) language, like Java, Python, PHP, Perl. All of these do not have this issue with memory-buffers. Their interpreters/compiler include code to handle all that, so the programmer is not bothered with that. If you do want to learn C, just continue to learn/try. In the end, a low-level language like C will hlp you understand better how computers work under the hood. Quote:
Here's a version of you program that uses fgets() with a fixed buffer. Just change the "100" in the #define to change the buffer size, and recompile. Code:
#include <stdio.h> |
All times are GMT -5. The time now is 05:25 AM. |