Reputation: 1
I've got an input as "SAME AS 1". Here, "SAME AS" is a string and "1" is the integer. How do i take them both as input if they are in the same line.
Using [^\n] doesn't help as it also takes the "1" as part of the string. Using [^0-9] doesn't help either since the same scanf command will have to take input as "LEFT" OR "RIGHT" which aren't ended with a digit.
Is there a way to combine the [^\n] and [^0-9]? Is there some other way?
P.S : The input cannot be changed.
Upvotes: 0
Views: 2781
Reputation: 753495
scanf()
doesn't care about newlinesUp to a point, you can do it like this:
#include <stdio.h>
int main(void)
{
char buffer[64];
int rc;
int number;
while ((rc = scanf("%63[^\n0-9]%d", buffer, &number)) != EOF)
{
if (rc == 0)
{
printf("Nothing read!\n");
int c;
while ((c = getchar()) != EOF && c != '\n')
;
}
else if (rc == 1)
printf("Simple word - no number [[%s]]\n", buffer);
else
printf("Word and number [[%s]] %d\n", buffer, number);
}
return 0;
}
This captures and tests the result of scanf()
. For example, given the data file:
SAME AS 1
LEFT
RIGHT
the program reads that as follows:
Word and number [[SAME AS ]] 1
Nothing read!
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]
It would be possible to add the 'character gobbling' loop after the 'word and number' report too. It might be better to create a micro-function to do that:
static inline void gobble(void)
{
int c;
while ((c = getchar()) != EOF && c != '\n')
;
}
Add a line to the data file with a number first, like this:
SAME AS 1
LEFT
RIGHT
123 ANGELS
and you get:
Word and number [[SAME AS ]] 1
Nothing read!
Simple word - no number [[LEFT]]
Word and number [[RIGHT]] 123
Simple word - no number [[ ANGELS]]
The scanf()
family of functions pay almost no attention to newlines or other white space except when you force them to do so. The whole file could
also be on a single line, or have each set of non-blanks on its own line and would produce much the same output.
If you want line based input, it is best to read lines and then parse the result. This also has the side benefit that you can more coherently report errors. For example:
#include <stdio.h>
int main(void)
{
char line[4096];
while (fgets(line, sizeof(line), stdin) != NULL)
{
char buffer[64];
int number;
int rc = sscanf(line, "%63[^\n0-9]%d", buffer, &number);
if (rc == 0)
printf("Nothing read! (line = [[%s]])\n", line);
else if (rc == 1)
printf("Simple word - no number [[%s]]\n", buffer);
else if (rc == 2)
printf("Word and number [[%s]] %d\n", buffer, number);
else
printf("sscanf() returned %d - can't happen (but did)?\n", rc);
}
return 0;
}
And runs on the first file:
Word and number [[SAME AS ]] 1
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]
and the second file:
Word and number [[SAME AS ]] 1
Simple word - no number [[LEFT]]
Simple word - no number [[RIGHT]]
Nothing read! (line = [[123 ANGELS
]])
It is very hard to use any of the scanf()
family of functions and avoid the trailing space on the SAME AS
data — unless you take advantage of 'two words plus number' or 'one word plus number' or 'one word', which would require the 'read line' example (second program) and multiple attempts with sscanf()
.
The scanf()
family of functions are very, very, very hard to use accurately. Very often, reading a line and using sscanf()
helps reduce the complexity, but it isn't perfect even then. See Beginner's Guide Away From scanf()
for more thoughts on the topic.
Upvotes: 2