inputting strings.

K

Kruton

What is the easiest way to take a string from a console while including
whitespaces? This program's user will input a line of text that will
consist of multiple tokens, but the number tokens and the length of each
line will vary at each use. Is there a way to get scanf to take a string
that contains whitespace? Or is there another function that would work?
-Thank you
 
P

Pieter Droogendijk

What is the easiest way to take a string from a console while including
whitespaces? This program's user will input a line of text that will
consist of multiple tokens, but the number tokens and the length of each
line will vary at each use. Is there a way to get scanf to take a string
that contains whitespace? Or is there another function that would work?
-Thank you

#include <stdio.h>
char buffer[bufsize];
fgets(buffer, bufsize, stdin);

Will read one line of text from standard input. Returns NULL on error or EOF, or
a pointer to the buffer on success.
Note that the newline is stored as well.
 
N

Nicola Mingotti

Kruton said:
What is the easiest way to take a string from a console while including
whitespaces?

/* ******** ex ****** */
#include<stdio.h>

int main(void){
char buffer[200];
printf("Write the string : ");
fgets(buffer,200,stdin);
printf("The string you wrote was : %s",buffer);
return 0;
}
/* ****************** */

bye.
 
P

pete

Kruton said:
What is the easiest way to take a string from a
console while including whitespaces?
This program's user will input a line of text that will
consist of multiple tokens, but the number tokens and the
length of each line will vary at each use.
Is there a way to get scanf to take a string
that contains whitespace?

/* BEGIN new.c */

#include <stdio.h>

#define STRINGLENGTH 160
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
char string[STRINGLENGTH] = {0};
int rc;

fputs("Enter a string with spaces: ", stdout);
fflush(stdout);
rc = scanf("%" xstr(STRINGLENGTH) "[^\n]%*[^\n]", string);
getchar();
if (rc > 0) {
printf("\nYour string is:\n\"%s\"\n", string);
}
return 0;
}

/* END new.c */
 
A

Al Bowers

pete said:
Kruton said:
What is the easiest way to take a string from a
console while including whitespaces?
This program's user will input a line of text that will
consist of multiple tokens, but the number tokens and the
length of each line will vary at each use.
Is there a way to get scanf to take a string
that contains whitespace?


/* BEGIN new.c */

#include <stdio.h>

#define STRINGLENGTH 160
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
char string[STRINGLENGTH] = {0};
int rc;

fputs("Enter a string with spaces: ", stdout);
fflush(stdout);
rc = scanf("%" xstr(STRINGLENGTH) "[^\n]%*[^\n]", string);

STRINGLENGTH-1.
The array string is not large enough to accept 160 chars plus a
nul-terminating character. That would be 161.
 
P

pete

Al said:
Kruton said:
What is the easiest way to take a string from a
console while including whitespaces?
This program's user will input a line of text that will
consist of multiple tokens, but the number tokens and the
length of each line will vary at each use.
Is there a way to get scanf to take a string
that contains whitespace?


/* BEGIN new.c */

#include <stdio.h>

#define STRINGLENGTH 160
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
char string[STRINGLENGTH] = {0};
int rc;

fputs("Enter a string with spaces: ", stdout);
fflush(stdout);
rc = scanf("%" xstr(STRINGLENGTH) "[^\n]%*[^\n]", string);

STRINGLENGTH-1.
The array string is not large enough to accept 160 chars plus a
nul-terminating character. That would be 161.

Thank you.

I meant to write:

char string[STRINGLENGTH + 1] = {0};

since the length of a string,
is one less than the total number of bytes.
 
S

Simon Biber

Nicola Mingotti said:
#include<stdio.h>

int main(void){
char buffer[200];
printf("Write the string : ");

You need to add a flush here to ensure that the prompt appears on the
screen before the system starts waiting for input.
fflush(stdout);
fgets(buffer,200,stdin);

Magic number alert - very bad idea. Use
fgets(buffer, sizeof buffer, stdin);
That way you can change the buffer size in one place only.

You should also check whether the fgets returned a null pointer. If
so, it is undefined behaviour to try to print buffer.
printf("The string you wrote was : %s",buffer);

If the user typed a string longer than 199 characters there will be
no newline character stored at the end of the buffer, which means the
stdout stream may not be valid, as it is not terminated properly.
 
T

The Real OS/2 Guy

What is the easiest way to take a string from a console while including
whitespaces? This program's user will input a line of text that will
consist of multiple tokens, but the number tokens and the length of each
line will vary at each use. Is there a way to get scanf to take a string
that contains whitespace? Or is there another function that would work?

getc() or getchar() is what you're looking for.

If your parser is simple you will write it on your own, else you may
use yacc/bison as a parser generator. Both uses getc() to have direct
access to the stream to avoid dynamic buffers.

Get a char, check it against the ones you will accept in the state you
are currently and when needed change the state.

You can easy accept token after token without a buffer (except the
token itself requires some kind of). You can convert any numerical
value on the fly wheras you sees any error directly.

You can use fscanf() or other library functions only if you sure that
you have a trusted input. But trusted input is only possible when you
accepts only files written by a well tested program.

Ever when you have to read anything from stdin you are sure that your
input is really untrusted and brings anything wrong. But no library
function will be ready to read any possible wrong things.

Even gets() tends to buffer overflow!

It will be more easy to write a little parser that reads char by chare
and acts on it as to handle a buffer that may be always to short to
get anything:
- you awaits a maximum line lengh of 80: the input is 81 - buffer
overflow or extra handling to extend the buffer until you have a
complete line readed in
- you awaits a maximum line length of 132: ther are 32K without '\n'
waiting in the stream.
- You awaits 32K - but the stream has 2GB without '\n'

You can't never handle all possible errors with the higher level
standard library functions.

Using token tables, getc()/getchar() makes it quite easy to extend the
functionality of your program without rewriting anything when you have
to handle a new token or change the token parameters.

ungetc() is designed to put a single char back into the input stream -
but the character you puts back can be any charater - not only the one
you've readed last!

Even as ungetc() is designed to put a single character it is not too
hard to write a wrapper around gtc()/ungetc to stack more than one
back. Yes, you must then use only the wrapper to read - but macros are
your friends anyway.

At least getc() is in no ways slower than (f)gets(), scanf() or
whatever, because all of them use getc() internally.
As you have to tokenise the stream you will win some runtime when you
use getc() directly, because you saves the (formatted) copy from one
puffer to another and scan that new puffer again (multiple times). You
can bring each char ito its real destionation and format on the fly
instead.

O.k., you may have some extra overhead to handle states - but make a
well design before you starts coding and you gets more flexibility for
free - and you saves the overhead the higher leveld library brings
with:
- dynamic buffer only to get a complete line
malloc() is a source of errors you have to handle
- breaking the line into tokens by copying the data partially from the
input buffer into another buffer
temp (buffer) -> destination field or another temp to convert from
string to something else
- checking the results of the library functions to make something
strange to come around
 
N

Nicola Mingotti

Simon Biber said:
Nicola Mingotti said:
#include<stdio.h>

int main(void){
char buffer[200];
printf("Write the string : ");

You need to add a flush here to ensure that the prompt appears on the
....

sure , i do agree with you :)
anyway the example was written to be
*very* simple ...
but it's true , i had to tell it ;)

bye.
 
M

MikeyD

Kruton said:
What is the easiest way to take a string from a console while including
whitespaces? This program's user will input a line of text that will
consist of multiple tokens, but the number tokens and the length of each
line will vary at each use. Is there a way to get scanf to take a string
that contains whitespace? Or is there another function that would work?
-Thank you

Well, the *easy* way is the gets(char[]) function to put text into an array,
but that has the minor disadvantage that if a user enters too long a string
you will overwrite your program's return value, which could leave you going
anywhere. A merely incompetent user might crash the kernel. A malicious one
could, in theory at least, execute arbitrary program code downloaded from
the internet.
If you're using gcc, there's a nice function called get_line() that will
automatically expand the string with malloc if someone enters a longer line.
Of course you have to create the char vector as dynamic memory, and this is
incompatiable with other compilers
Most people will use fgets(FILE*,char[],int), which reads input but won't go
outside the array. However, it makes you specify stdin each time and won't
delete the trailing \n.
If you know what you want it for, I'd recommend you write your own
getstring(char[],int) function, which lets you choose your own terminator
value, error messages etc. Here's mine as an example (with a few #defines
for you to customize)
#include <stdio.h>
#define TERMINATOR '\n'
#define SUCCESS 1
#define FAIL 0
//if you want to return the number of characters read
//#define CHARS
//if you want a printed error message when too much is entered
//#define MSG
int getstring(char* a, int len){
for(int i=0;;i++){
a=getchar();
if(a==TERMINATOR){
a='\0';
#ifdef CHARS
return i;
#else
return SUCCESS
#endif
}
if(i==len){
a='\0';//to give a proper string even though it won't contain
all the input
#ifdef MSG
fprintf(stderr,"Error: Invalid string: Too many characters before
TERMINATOR")
//replace TERMINATOR manually, probably with "ENTER"
#endif
return FAIL;
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top