📄 int_streams.c
字号:
return(c);}/* * Getting a char from the stdin * * if delay is non negative, waiyts only for delay seconds */long GetChar(LWFLOAT delay){ return(FGetChar(stdinStream,delay));}/* * Command for getting a char */void C_GetChar(char **argv){ unsigned long c; char str[2]; char *var; LWFLOAT delay; argv = ParseArgv(argv,tVNAME_,NULL,&var,tFLOAT_,-1.,&delay,0); c = GetChar(delay); SetResultStr(KeyCode2Str(c,NO)); str[0] = c; str[1] = '\0'; if (var != NULL) SetStrVariable(var,str);}/**************************************************** * * Functions and commands for getting a whole line * ****************************************************/ /* * Main function for getting a line from any stream * The terminal mode has been set previously and will * be restored before this function returns. * This function returns 1 or EOF */static int _FGetLine(STREAM stream, char *str){ long l; char *str1,*line,c; if (stream->mode != StreamRead) Errorf("FGetLine() : stream '%d' not readable",stream->id); /* Init the string */ *str = '\0'; /* * We separate the 3 cases of streams */ /* Case the input is the terminal */ if (stream == _StdinStream) { if (toplevelCur->termMode != CommandTMode) DoLineTerm(); for (line = toplevelCur->termLine;*line != '\0'; line++) if (*line == NewlineKC /*|| *line == EofKC */) break; if (*line == '\0') return(NO); toplevelCur->termMode = toplevelCur->oldTermMode; /* Looking for the new line or the end of file */ for (line = toplevelCur->termLine;*line != '\n' && *line != '\r' && *line != '\0' ; line++); /* Case there is just an end of file */ if (*line == '\0' && line == toplevelCur->termLine) return(EOF); /* Skip the eventual \n */ c = *line; if (c != '\0') line++; /* Pull one line from the current terminal line */ PullTermLine(line,str); /* Take out the eventual '\n' */ if (c != '\0') str[strlen(str)-1] = '\0'; return(1); } /* Case it is a file stream */ if (stream->buffer == NULL) { l = fscanf(stream->stream,"%[^\n\r]",str); if (feof(stream->stream) && l == EOF) return(EOF); else { fgetc(stream->stream); return(1); } } /* Case it is a string stream */ str1 = str; while(l = PullBuffer(stream->buffer)) { if (l == '\n' || l == '\r' || l == EofKC) break; *(str++) = l; } *str = '\0'; if (str1 != str) return(1); if (l == EofKC) return(EOF); return(1);}/* * Getting a line from any stream * returns 1 or EOF */int FGetLine(STREAM stream, char *str){ /* We set the terminal mode (if the input is the terminal) and just call _FGetLine */ if (stream == _StdinStream) { toplevelCur->oldTermMode = toplevelCur->termMode; toplevelCur->termMode = ScanTMode; } return(_FGetLine(stream,str)); }/* * Getting a command from any stream * returns 1 or EOF * The only difference with the above function is the terminal mode. */int FGetCommandLine(STREAM stream, char *str){ /* We set the terminal mode (if the input is the terminal) and just call _FGetLine */ if (stream == _StdinStream) { toplevelCur->oldTermMode = toplevelCur->termMode; toplevelCur->termMode = CommandTMode; } return(_FGetLine(stream,str)); }/* * Getting a line from stdin */int GetLine(char *str){ return(FGetLine(stdinStream,str));}/* * Getting a command from stdin */int LWGetCommandLine(char *str){ return(FGetCommandLine(stdinStream,str));}/* * Command for Getting a line from stdin */void C_GetLine(char **argv){ char str[2000]; int ans; char *var; argv = ParseArgv(argv,tVNAME_,NULL,&var,0); ans = GetLine(str); if (var != NULL) { SetStrVariable(var,str); if (ans != EOF) SetResultInt(ans); else SetResultStr("eof"); } else SetResultStr(str);}/**************************************************** * * Commands for input * ****************************************************//* * The main function for the scanf and sscanf commands * string : a pointer to the string to analyze or NULL * stream : a pointer to the file stream to analyze or NULL * (only one of the two values above must be not NULL) * nArgs : a pointer to what will be the number of arguments read * argv : the list of all the variable's names. * * returns NO, YES or EOF */static int _CScanf(char **string,FILE * stream,int *nArgs, char **argv){ int n,res; int nChars; char *format,*theFormat; char format1[1000]; char *str; char argType,flagSetVariable; int ival; LWFLOAT fval; char sval[1000],*var; /* Some checks */ if (stream != NULL && string != NULL) Errorf("_CScan() : cannot pass both a stream and a file"); if (stream == NULL && string == NULL) Errorf("_CScan() : you must pass either a stream or a file"); /* Then parse the format */ argv = ParseArgv(argv,tSTR,&format,-1); if (strlen(format) > 990) Errorf("_CScanf() : format is too long"); /* Make some initialization */ *nArgs = 0; nChars = 0; theFormat = format; /* Loop on the string or the stream */ while(1) { /* If we reached the end of the format --> return(YES) */ if (*format == '\0') return(YES); /* * STRING : First we match whatever is before the first % sign */ if (string != NULL) { /* First we read whatever is before the % sign */ while (*format != '\0' && *format != '%') { /* Case *format == ' ' || '\n' ==> we read as many blanks as possible in the string */ if (*format == ' ' || *format == '\n') { while (**string == ' ') {*string += 1;nChars++;} /* Spaces before the '\n' */ if (*format == '\n') { /* The '\n' */ if (**string != '\n') return(NO); *string+=1; nChars++; } format++; continue; } /* Otherwise *format has to match */ if (*format != **string) return(NO); *string+=1; nChars++; format++; } /* If we reached the end of the string before the end of the format --> return EOF (unless format == %n) */ if (**string == '\0' && *format != '\0' && strncmp(format,"%n",2)) return(EOF); /* If *format did not match --> return NO */ if (*format != '%' && *format != **string) return(NO); /* If we read all the format --> return YES */ if (*format == '\0') return(YES); /* Case we stopped at a %% sign */ if (format[1] == '%') { if (**string != '%') return(NO); *string+=1; nChars++; *format += 2; continue; } } /* * STREAM : First we match whatever is before the first % sign */ else { /* We read in 'format1' everything before the first % (which is not a %%) */ str = format1; while (*format != '\0' && (*format != '%' || *(format+1) == '%')) *(str++) = *(format++); /* If we did read something then we fscanf (after adding %n) */ if (str != format1) { *str = '\0'; strcat(format1,"%n"); n = -1; /* During this fscanf, it reads the 'format' AND all the spaces that follow */ res = fscanf(stream,format1,&n); if (n != -1) nChars += n; if (res == EOF) return(EOF); continue; } } /* * So now 'format' is pointing to the '%' argument --> so let's get the format in 'format1' ! */ str = format1; if (format[1] == '\0') Errorf("'%%' without a type in scanf format : '%s'",theFormat); *(str++) = *(format++); while (*format != '\0' && *format != '%' && !isalpha(*format) && *format != '[') *(str++) = *(format++); /* if we found a '[' then we just have to look for the matching ']' */ if (*format == '[') { while (*format != '\0' && *format != ']') *(str++) = *(format++); if (*format != ']') Errorf("Missing ']' in scanf format : '%s'",theFormat); } /* read 1 more char if needed */ if (isalpha(*format) || *format == ']') { argType = *format; *(str++) = *(format++); } else Errorf("Bad format in 'scanf' : '%s'",theFormat); /* End 'format1' ad concatenates a %n */ *str = '\0'; strcat(str,"%n"); /* Is it a %* type of format ? */ if (format1[1] == '*') flagSetVariable = NO; else flagSetVariable = YES; /* * So let's read the next argument corresponding to 'format1' */ /* Case of an int */ if (argType == 'd' || argType == 'i' || argType == 'o' || argType == 'x') { n = -1; if (string != NULL) res = sscanf(*string,format1,&ival,&n); else res = fscanf(stream,format1,&ival,&n); if (n != -1) { nChars += n; if (string != NULL) *string+=n; } if (res == EOF) return(EOF); if (res == 0) return(NO); if (flagSetVariable) { argv = ParseArgv(argv,tVNAME,&var,-1); SetNumVariable(var,ival); *nArgs += 1; } } /* Case of a LWFLOAT */ else if (argType == 'e' || argType == 'f' || argType == 'g') { n = -1; if (string != NULL) res = sscanf(*string,format1,&fval,&n); else res = fscanf(stream,format1,&fval,&n); if (n != -1) { nChars += n; if (string != NULL) *string+=n; } if (res == EOF) return(EOF); if (res == 0) return(NO); if (flagSetVariable) { argv = ParseArgv(argv,tVNAME,&var,-1); SetNumVariable(var,fval); *nArgs += 1; } } /* Case of a string */ else if (argType == 's' || argType == ']') { n = -1; if (string != NULL) res = sscanf(*string,format1,sval,&n); else res = fscanf(stream,format1,sval,&n); if (n != -1) { nChars += n; if (string != NULL) *string+=n; } if (res == EOF) return(EOF); if (res == 0) return(NO); if (flagSetVariable) { argv = ParseArgv(argv,tVNAME,&var,-1); SetStrVariable(var,sval); *nArgs += 1; } } /* Case of a char */ else if (argType == 'c') { n = -1; if (string != NULL) res = sscanf(*string,"%c%n",sval,&n); else res = fscanf(stream,"%c%n",sval,&n); if (n != -1) { nChars += n; if (string != NULL) *string+=n; } if (res == EOF) return(EOF); if (res == 0) return(NO); sval[1] = '\0'; if (flagSetVariable) { argv = ParseArgv(argv,tVNAME,&var,-1); SetStrVariable(var,sval); *nArgs += 1; } } /* Case of a %n */ else if (argType == 'n') { argv = ParseArgv(argv,tVNAME,&var,-1); SetNumVariable(var,nChars); } /* Case unknown */ else Errorf("_CScanf() : Format '%c' unknown in '%s'",argType,theFormat); } return(YES);}/* * The 'scanf' command */void C_Scanf(char **argv){ STREAM stream; char str[1000],*str1,*str2; int nArgs; int result; /* Get the current stdin */ stream = toplevelCur->in; /* * Case of the terminal (wait for \n or an eof) */ if (stdinStream == _StdinStream) { toplevelCur->oldTermMode = toplevelCur->termMode; toplevelCur->termMode = ScanTMode; DoLineTerm(); toplevelCur->termMode = toplevelCur->oldTermMode; str1 = toplevelCur->termLine; _CScanf(&str1,NULL,&nArgs,argv); result = nArgs; PullTermLine(str1,NULL); } /* Case of a string buffer */ else if (stream->buffer != NULL) { Buffer2Str(stream->buffer,str); str1 = str; _CScanf(&str1,NULL,&nArgs,argv); result = nArgs; str2 = str; while(str2 != str1) { PullBuffer(stream->buffer); str2++; } } /* Case of a stream */ else { _CScanf(NULL,stream->stream,&nArgs,argv); result = nArgs; } SetResultInt(result);}/* * The 'sscanf' command */void C_SScanf(char **argv){ char *str1; char *theString; int nArgs; int result; argv = ParseArgv(argv,tSTR,&theString,-1); str1 = theString; result = _CScanf(&str1,NULL,&nArgs,argv); SetResultInt(nArgs);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -