-3

I am writing a simple C ++ program as my homework to count the number of numbers in a text file. Below is my code, but unfortunately it counts words and numbers. I have no idea how it should count the number of numbers, where is the error?

My text file:

lorem ipsum 5 87 451 13

My code:

#include <iostream>
#include <cstdio>
#include <fstream>

using namespace std;


int main()
{
    int n=0;
    char plik[100], liczby[100];
    
    string nazwapliku;
    nazwapliku="file.txt";
    
    ifstream we("file.txt");
    
    if (!we)
    {
        cout<<"Can't read file'";
        cin.ignore();
        getchar();
        return 1;
    }
    while (!we.eof())
    {
        we>>liczby;
        if(we)
            n=n+1;
    }
    we.close();
    cout<<"Numbers count in "<<nazwapliku<<" : "<<n;
    getchar();
    return 0;
}
  • There isn't any error, you just haven't done the work to tell if `liczby` is a number or not. You have to think of a way to tell the difference between words and numbers (that part is easy), then you have to write the code to implement that (maybe more difficult). – john Dec 21 '20 at 19:38
  • Are you trying to count the number of digits (`[0-9]`) in the file? Or the number of multi-digit integers? Or the number of floating point numbers? Scientific notation numbers? Just "numbers" isn't very descriptive. – scohe001 Dec 21 '20 at 19:40
  • 1
    Related to above comment: [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – user4581301 Dec 21 '20 at 19:40
  • @scohe001 I have text file with some words and few random numbers. I must write program to count only numbers in text file. My numbers are 1,15,98,123, 452 and etc – Błażej Mężyński Dec 21 '20 at 19:43
  • @BłażejMężyński This should point you into the right direction what to do: https://stackoverflow.com/questions/24504582/how-to-test-whether-stringstream-operator-has-parsed-a-bad-type-and-skip-it – πάντα ῥεῖ Dec 21 '20 at 19:55

1 Answers1

1

Let's start off with two very important things which apply to all programs you are going to write:

  1. Never ever read unconstrained into a buffer - ever! That is the primary attack vector for hackers trying to subvert your program by overwriting what comes after buffer. Always limit the input the maximum space allowed, e.g., setting up the width of the buffer using std::setw(liczby). In nearly all cases in C++ you'd want to use std::string instead of a fixed size character buffer. These don't have problem of buffer overruns (it may still be desirable to limit the maximum amount of space they take which can be done with allocators).

  2. Always test whether input was successful before you use the input. Doing so does not involve stream.eof() as that condition only holds when the program has exhausted all input. Also you need to check after reading (as the loop isn't written idiomatic, I didn't notice that you actually do check if (we); it is worth writing the loop idiomatic, though). For example, your loop could reasonably look like (if it weren't for the second point):

    while (we >> std::setw(sizeof(liczby) >> liczby) {
       // ...
    }
    

As your program only tries to read words, it obviously only counts the number of words. To count "numbers" which seem to be sequences of digits for your assignment you'll need check whether a given word consists of only numbers (and in case you are trying to use std::isdigit() from <ccctype> please be aware that this function only accepts positive int while char is normally signed, i.e., you'd need to cast your char to unsigned char before feeding them into std::isdigit()). I leave the actual implementation as an exercise, though.

Dietmar Kühl
  • 141,209
  • 12
  • 196
  • 356