![]() |
|
|
#188 |
|
Jun 2003
117378 Posts |
|
|
|
|
|
|
#189 | ||
|
Aug 2005
Seattle, WA
2·883 Posts |
Quote:
Quote:
The problem with just calling getchar is that you don't really know if there's anything else on that first line after the number. E.g. if there's a space after it, then you'll have the same problem. The real solution is to let your code match your conception of what the program is doing. That is, you're trying to have your program operate in an inherently line-by-line fashion. So your code should work in a line-by-line way as well. The usual way to do something like that is to always read whole lines (using fgets, or if you're really concerned about truncating lines that are too long, using a function of your own devising which reads a whole line and returns it, as we discussed before). Once you've read the line containing the shift count, use sscanf to read the number out of it. Then, when you go to read the source text you will be ready to read a whole new line of input. And BTW, you should check out the isupper and islower functions, defined in ctype.h. |
||
|
|
|
|
|
#190 |
|
Basketry That Evening!
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88
3×29×83 Posts |
Yes, most of that occurred to me while I was in bed trying to sleep. My next question was going to be "Is there a function to clear the stdin, or do I just have to use the getchar() and assume the input is as requested?" Then it occurred to be that an fgets(NULL,...) call will work fine.
I did google sscanf, and got this. Apparently scanf is deprecated? The read-a-whole-line than search for what you want does seem to be a better method, not only because of the whole-line-ness but also the error catching. Good to know, thanks again. (Edit: What's the difference between fgets and getline?) Last fiddled with by Dubslow on 2012-02-24 at 22:57 |
|
|
|
|
|
#191 |
|
If I May
"Chris Halsall"
Sep 2002
Barbados
978210 Posts |
|
|
|
|
|
|
#192 |
|
Basketry That Evening!
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88
3×29×83 Posts |
I can use fgets and just not use the info, even if that's not the right way to do it.
Scratch that. Just gonna read the whole line than sscanf the string for shift, as suggested above. Edit2: Code:
char * scan = (char *)malloc( MAXSTRLEN * sizeof(char));
do {
printf("Please enter the shift value (between -25..-1 and 1..25)\n");
fgets( scan, MAXSTRLEN, stdin);
badin = (sscanf(scan, "%d", &shift) != 1)
||
( !(((-25 <= shift) && (shift <= -1)) || ((1 <= shift) && (shift <= 25))) );
/* A somewhat obfuscated line of code; if shift is not in [-25,-1]U[1,25] OR sscanf didn't assign correctly, then badin is set to true. */
if (shift == 999) {
secret = 1;
badin = 0;
} else if (shift == -999) {
usecret = 1;
badin = 0;
}
if (badin)
printf("%d is not a valid shift value.\n", shift);
} while (badin);
if (secret || usecret)
printf("Using position shift\n");
else
printf("Using shift value of %d\n", shift);
if (shift < 0)
shift += 26;
while (1) {
printf("Please enter the source text (empty line to quit)\n");
char * string = (char *)malloc( MAXSTRLEN * sizeof(char));
fgets(string, MAXSTRLEN, stdin);
i = (int)strlen(string);
if( i == (MAXSTRLEN - 1) ) { // Then the string is longer than MAXSTRLEN - 1, and so the rest is lost.
printf("Source is longer than %d characters. The rest is lost.\n", MAXSTRLEN-1); // will add in realloc later once the behavior is correct
}
if ( string[0]=='\n' ) { // The entire string is null, or rather, the only character was \n, so no input.
printf("Bye.\n");
return 7;
}
printf("Source : ");
Last fiddled with by Dubslow on 2012-02-24 at 23:13 |
|
|
|
|
|
#193 |
|
If I May
"Chris Halsall"
Sep 2002
Barbados
2·67·73 Posts |
|
|
|
|
|
|
#194 |
|
Basketry That Evening!
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88
3×29×83 Posts |
Seg fault, to be precise
|
|
|
|
|
|
#195 | |
|
Aug 2005
Seattle, WA
2×883 Posts |
Quote:
1) scanf is not deprecated, at least in any official sense that I'm aware of. 2) It doesn't make clear that getline is not part of the standard library, while the other functions mentioned are. I.e. any C implementation will always have things like scanf and fgets available, but some will not have getline, and even worse, some will have getline but have it defined differently. 3) The functions which this site describes as deprecated *can* be used unsafely, but need not be. E.g. it gives an example of how using scanf with a bare %s conversion can be unsafe. However, it is entirely possible to use scanf in safe ways. Similarly, there's nothing unsafe about fgets when used correctly. It can be a pain to use, but it can be used with complete safety. By contrast, gets can *never* be used safely, and the advice to avoid it is good. At any rate, I will reiterate what I said earlier about reading a line at a time. In fact, I'll go further. As an exercise, you should write the implementation of the following function: char *ReadLine(FILE *stream); It should read exactly one line (as delimited by the '\n' character) from the given stream, consuming that '\n' but not placing it in the returned array. The return value will be a pointer to an array exactly long enough to hold the entire line (including a trailing '\0' but minus the '\n'), allocated with malloc. There should be no limit on the size of line that it can handle (other than exhausting the machine's memory). It will be the caller's responsibility to free this array when (s)he is done with it. If there are no characters at all left in the stream when it is called (i.e. it's at EOF), it should return NULL. Compare this to the case where the first character it reads is a newline; what should it return in that case? I think you will find it to be instructive to write this function, and you may also find it very useful for exactly the kind of program you're trying to write now. |
|
|
|
|
|
|
#196 |
|
Aug 2005
Seattle, WA
2×883 Posts |
|
|
|
|
|
|
#197 |
|
Basketry That Evening!
"Bunslow the Bold"
Jun 2011
40<A<43 -89<O<-88
3·29·83 Posts |
Yessir, thank you sir, will do sir
![]() Thanks for pointing out the mem leak, I certainly didn't catch it. However, moving the declaration outside the loop should be sufficient to fix it (right?). Quick question: What does realloc(ptr,n) do if( n<sizeof(ptr) ) ? Does it return ptr? Quick question 2: If I have Code:
char arr[80]; Code:
sizeof(arr) // ==80? Quick question 3: What happens if I get an EOF before \n? Just fill in the \0? (And, further, if the first char is \n, do I return a one-char string "\0" or NULL?) Last fiddled with by Dubslow on 2012-02-25 at 01:38 |
|
|
|
|
|
#198 | ||
|
Aug 2005
Seattle, WA
176610 Posts |
Hey, it's just a suggestion. Take it or leave it.
![]() Quote:
Quote:
Anyway, this call to realloc sets the allocated size to n, regardless of how big the allocated space was before.* If that means the allocated space shrinks, then any data you had beyond byte n is lost. Does that answer your question? *This assumes that realloc is actually able to satisfy the request. In practice this will always be true if you're trying to shrink the space. If you're trying to grow it, then it's possible that there's no block of contiguous space of the requested size, in which case realloc will return NULL, leaving the space still allocated. |
||
|
|
|