开发者

Reading an integer and / or character without an array

I need to read an integer one by one until i read a '$', and then to determine the largest, smallest and so on. I could use a character variable and do it, but it works for numbers from 0 to 9. But how do I read integers of two or more digits and at the same time, detect a '$' - I used a char *, but I 开发者_运维技巧guess it is equivalent to an array, which I should not use here. Also, char holds a single number / char, hence not suitable for larger numbers. What should I do?


No arrays, no pointers, no tricky char-by-char read & convert. Just plain scanf and getchar.

#include <stdio.h>

int main()
{
    int newValue=0;        /* value being acquired */
    int max;               /* current maximum value */
    int min;               /* current minimum value */
    int firstAcquired=0;   /* boolean flag set to 1 after first acquisition */
    int ch;                /* used as temporary storage for the getchar() */
    for(;;)
    {
        /* scanf returns the number of successfully acquired fields; here if it
           returns 0 means that the value couldn't be acquired */
        if(scanf("%d",&newValue)==0)
        {
            /* scanf failed, but it's guaranteed it put the offending character
               back into the stream, from where we can get it */
            ch=getchar();
            if(ch=='$' || ch==EOF)
                break;
            else
            /* from here to the break it's just to handle invalid input and EOF
               gracefully; if you are not interested you can replace this stuff
               with a random curse to the user */
            {
                puts("Invalid input, retry.");
                /* Empty the buffer */
                while((ch=getchar())!='\n' && ch!=EOF)
                    ;
            }
            /* if it's EOF we exit */
            if(ch==EOF)
                break;
        }
        else
        {
        /* Everything went better than expected */
            if(!firstAcquired || newValue>max)
                max=newValue;
            if(!firstAcquired || newValue<min)
                min=newValue;
            firstAcquired=1;
        }
    }
    if(firstAcquired)
    {
        printf("The maximum value was %d\n", max);
        printf("The minimum value was %d\n", min);
    }
    return 0;
}


In the interest of spoiling all the fun, showing off, outright overkill and darn tooting fun:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/karma.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
namespace qi = boost::spirit::qi;

template <typename V>
void show_statistics(const V& data)
{
    using namespace boost::spirit::karma;
    std::cout << "data:\t"<< format('{' << auto_ % ", " << '}', data) << std::endl;

    std::cout << "min:\t" << *std::min_element(data.begin(), data.end()) << std::endl;
    std::cout << "max:\t" << *std::max_element(data.begin(), data.end()) << std::endl;

    auto sum = std::accumulate(data.begin(), data.end(), 0);
    std::cout << "sum:\t" << sum << std::endl;
    std::cout << "avg:\t" << (1.0*sum) / data.size() << std::endl;
}

void dostats(const std::vector<int>& data) { show_statistics(data); }

int main()
{
    std::cin.unsetf(std::ios::skipws);
    auto f = boost::spirit::istream_iterator(std::cin);
    decltype(f) l;

    bool ok = qi::phrase_parse(f, l, +(+qi::int_ > "$") [ dostats ], qi::space);

    if (f!=l)
        std::cout << "Remaining input unparsed: " << std::string(f,l) << std::endl;

    return ok? 0:255;
}

Demo:

Sample run:

sehe@natty:/tmp$ ./test2 <<< "1 2 3 4 5 $ 3 -9 0 0 0 $ 900 9000 $ unparsed trailing text"
data:   {1, 2, 3, 4, 5}
min:    1
max:    5
sum:    15
avg:    3
data:   {3, -9, 0, 0, 0}
min:    -9
max:    3
sum:    -6
avg:    -1.2
data:   {900, 9000}
min:    900
max:    9000
sum:    9900
avg:    4950
Remaining input unparsed: unparsed trailing text


You can use 'scanf("%s")' to read a group of characters. You can then check if the first character is a '%' and terminate if so. Otherwise, call atoi to convert to an integer. Store the largest and smallest in integer types, not character types.

Basically, the only time you have to deal with characters is when you read them in and check if it's a '$'. Otherwise, use integers all the way through.


If I'm getting what you want correctly it should be something like this:

int i = 0;
char c = getchar();
while (c != '$')
{
    i = i * 10 + (c - '0');
    c = getchar();
}

Hope it helped.


You can read char by char in a loop, check values and so on...

int i = 0;
char c = 0;
int size = 10;
int currentIndex = 0;
int* integers = malloc(sizeof(int) * size);
int counter = 0;
do
{
    scanf("%c", &c);
    if (c == ' ') // Match space, used a number separator
    {
        if (counter != 0 && i != 0)
        {
            if (currentIndex >= size)
            {
                size += 5;
                integers = realloc(integers, size);
            }
            integers[currentIndex] = i;
            currentIndex++;
        }
        counter = 0;
        i = 0;
    }
    else if (c >= '0' && c <= '9')
    {
        i = (i * counter * 10) + (c - '0');
        counter++;
    }
}
while(c != '$');

Don't forget to free integers in the end!


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define BUFF_SIZE 16
#define DATA_MAX_SIZE 64

int main(){
    char buff[BUFF_SIZE];
    int data[DATA_MAX_SIZE];
    int i,value,counter = 0;
    char *buffp,*p;
    while(NULL!=fgets(buff,BUFF_SIZE,stdin)){
        buff[BUFF_SIZE - 1]='\0';
        buffp = buff;
next:   while(isspace(*buffp))
            ++buffp;
        if(*buffp == '\0')
            continue;
        value = strtol(buffp, &p, 0);
        if(counter == DATA_MAX_SIZE){
            printf("over data max size!\n");
            break;
        } else if(p != buffp){
            data[counter++]=value;
            if(*p == '\0' || *p == '\r'|| *p == '\n')
                continue;
            buffp = p;
            goto next;
        } else {
            if(*p == '$')
                break;
            printf("format error\n");
            break;
        }
    }
    //check code 
    for(i=0;i<counter;++i){
        printf("data[%d]=%d\n",i, data[i]);
    }
    return 0;
}

OUTPUT:

1 2 3
123
456
99 $
data[0]=1
data[1]=2
data[2]=3
data[3]=123
data[4]=456
data[5]=99

12345

4
$
data[0]=12345
data[1]=4
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜