C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 09-16-2008, 10:03 AM   #16
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Ah, that's because you "wait for user input" using getchar() at the end of the program, but if have entered 8000 characters, and fgets() accepted 149 of them, the first of the 7851 left overof will happily be received by getchar(), and your program finishes. So it's doing exactly what you expect.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 09-16-2008, 10:19 AM   #17
Registered User
 
Join Date: Sep 2008
Location: Nort East of Great Britain!
Posts: 8
Blimey! I never thought of that.

Stdin is a strange creature, isn't it?

Thanks for clearing that up.
Klint777 is offline   Reply With Quote
Old 09-16-2008, 11:26 AM   #18
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,944
If your problem here is all about buffer length, I think you should stop trying to solve a problem that may not exist in practice.

Do correct me if I'm wrong but there are three possibilities: 1) the input already exists in a file, so you can get the size that way.
3) the input is coming thru a pipe, etc., in which case it will/can be bufferered to a specific length and you use that 2) the input doesn't exist yet and will be entered by the user, in which case you use a TEMPORARY giant buffer and strlen.

I very much doubt it would ever be necessary to realloc() one character at a time, etc. Remember char buffer[8192] is still only 8k of memory, 5-10 pages of actual text.
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS

Last edited by MK27; 09-17-2008 at 08:06 AM.
MK27 is offline   Reply With Quote
Old 09-17-2008, 04:54 AM   #19
Registered User
 
Join Date: Sep 2008
Location: Nort East of Great Britain!
Posts: 8
My main concern, at the beginning, was with file/user input. In the form of strings.

I don't want to just declare a huge array, and hog that memory 'in case' the user puts loads of characters in - neither did I want to limit the amount of characters.

The whole concept of a temporary "giant buffer" didn't occur in any form. But its seems the most robust system to use.

Again, thanks for all the info. Its been a big help.

Its just an odd transition from Academic programming, and trying to find solutions for problems based in reality. It seems for every titbit I learn, I realize just how much more I didn't even realize I didn't know.

User input, here, being a prime example.

Clint
Klint777 is offline   Reply With Quote
Old 09-17-2008, 05:15 AM   #20
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
If, for some reason, you think that a huge buffer isn't the right solution, another method that does work is to check the last character of the input you got from fgets() - if it's a newline, then you got the whole line. If it's not a newline, there is more of that line sitting around waiting to be read [or you got to the end of the file and there was no newline on the final bit of text, in the case of reading text files]. How you handle this depends on what your application is actually trying to achieve - does it NEED to cope with 8000+ character long lines, or is it expected to have only short lines, so we can output an error message and say "Sorry, can't read this line at line number X, it's too long" and quit?

In some cases, it may also not matter if you take the input as two or more chunks. Just keep calling fgets() until you have processes all of the lines...

A program should not CRASH from abnormal input, so if your application is reading from stdin, a good test to see that it doesn't crash is to feed the program with itself:
Code:
$ myprog < myprog
or
Code:
c:\>myprog < myprog.exe
.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Old 09-17-2008, 07:21 AM   #21
subminimalist
 
MK27's Avatar
 
Join Date: Jul 2008
Location: NYC
Posts: 3,944
Quote:
Originally Posted by matsp View Post
If, for some reason, you think that a huge buffer isn't the right solution, another method that does work is to check the last character of the input you got from fgets() - if it's a newline, then you got the whole line.
Where did you put all the characters you fgot before the newline?
__________________

Accuracy and integrity mean nothing if you don't make it past the censors...PYTHAGORAS
MK27 is offline   Reply With Quote
Old 09-17-2008, 07:37 AM   #22
Kernel hacker
 
Join Date: Jul 2007
Location: Farncombe, Surrey, England
Posts: 15,686
Quote:
Originally Posted by MK27 View Post
Where did you put all the characters you fgot before the newline?
Eh? if NORMAL behaviour is relative short lines, then you can deal with the problem in this way:
Code:
while(fgets(str, ...) != NULL)
{
    if (strrchr(str, '\n') == NULL)
    {
      // didn't get a whole line. 
      int ch;
      printf("Very long line, skipping it.\n");
      while((ch = fgetc(...)) != '\n' && ch != EOF) ; 
    }
}
If you EXPECT to get very long lines [or at least can sort of guess that it MAY happen], then you may need to deal with arbitrary length lines and have to gather it all up in one big lump, something like this:
Code:
int uselongline = 0;
char *longline = NULL;
while(fgets(str, ...) != NULL)
{
    char *newline = strrchr(str, '\n');
    if (newline || uselongline)
    {
       longline = realloc(verylongline, strlen(longline) + strlen(str) + 1);
       strncat(longline, str);
       if (newline)  // We've got the whole line
       {      
          dosomething(longline);
          free(longline);
          longline = NULL;
          uselongline = 0;
        } else {
          uselongline = 1;
        }
    }
    else
    {
        dosoemthing(str);
    }
}
Note that 8192 may not be sufficient for some purposes. We had an example of badly written software that read a symbol file. When using templates in C++, you can get pretty long symbols. The software was happy with symbols up to about 1500 characters, anything longer would crash(!), but our symbol file had some 9000 character long strings.

The important point here is that we (sometimes) need to recognize that we get input beyond what we have space for, and we need to do SOMETHING about it. What is right in one case may be wrong in another.

--
Mats
__________________
Compilers can produce warnings - make the compiler programmers happy: Use them!
Please don't PM me for help - and no, I don't do help over instant messengers.
matsp is offline   Reply With Quote
Reply

Tags
c programming, delightful features, input, puzzlement

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ ini file reader problems guitarist809 C++ Programming 7 09-04-2008 06:02 AM
String editor for a sentence inputted by a user - any suggestions or ideas? the_newbug C Programming 4 03-03-2006 02:11 AM
Classes inheretance problem... NANO C++ Programming 12 12-09-2002 03:23 PM
creating class, and linking files JCK C++ Programming 12 12-08-2002 02:45 PM
Warnings, warnings, warnings? spentdome C Programming 25 05-27-2002 06:49 PM


All times are GMT -6. The time now is 04:11 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22