-1

I am currently learning C programming (my experience is in Python, Java and Swift). I am trying to count how many numbers are on the first line of a text file.

The text file looks a bit like this:

-54 37 64 82 -98 
...

I have tried various different ideas that I have had. The first was to check each character in turn for the EOL, and if it wasn't to add 1 to the total. I quickly realised this only works for single digit numbers, and not general integers.

I then tried to use fscanf to find the last number on the line, and then rewind and use fscanf to count each number until that last number was found again:

int temp;
FILE *fd = fopen("test.txt", "r");

fscanf(fd, "%d\n", &temp);
printf("Last Number on Line is: %d\n", temp);

However before I could even write the next logic to count the numbers I realised that this printed Last Number on Line is: -54 which was not the expected output from the above file example.

At this point I am rather stuck. Searching online mainly returns results on how to count how many lines are in a file due to the similarity of the question.

Any help would be much appreciated!

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Harry Day
  • 378
  • 4
  • 13
  • 1
    I would probably loop over the characters of the string and have a flag stating whether or not the current position is within a number. Whenever that changes from true to false, increment the counter. – 500 - Internal Server Error Oct 31 '22 at 19:31
  • 2
    If you have a pre-determined hard limit on the maximum line length, this is fairly trivial: read the line with `fgets` and then use `strtol` iteratively to parse the input line. If you don't have such a max line limit, you can try using `getline` (if it's available). It's a fun exercise to do it with `fgets` and a small buffer that does not hold a full line. Also fun to read 1 character at a time with a state machine. (eg, you must detect that `-1+5` is not a single value). It is neither fun nor educational to do this with `scanf`. – William Pursell Oct 31 '22 at 19:34
  • I'll give that a try after dinner and see what I come up with, thanks – Harry Day Oct 31 '22 at 19:37
  • You can also use `sscanf` with a string pointer and the format spec `"%d%n"` which will tell you the value and the index it stopped scanning. You can use that to advance the string pointer and work your way along the string extracting numbers. – Weather Vane Oct 31 '22 at 19:57
  • Be aware of [the effect of trailing white space in a `scanf()` format string](https://stackoverflow.com/questions/19499060/what-is-the-effect-of-trailing-white-space-in-a-scanf-format-string) — avoid it. – Jonathan Leffler Oct 31 '22 at 20:57

2 Answers2

0

In the end I have used the suggestion here and come up with the following solution:

char buffer;
int  temp = 0;
int  row_count = 0;

while((buffer = getc(fd)) != '\n') {
    if (temp == 0 && (isdigit(buffer))) {
        col_count += 1;
        temp = 1;
    } else if (temp == 1 && buffer == ' ') {
        temp = 0;
    }
}

This is working fine for me in the context I am using it within, thanks for the help

Harry Day
  • 378
  • 4
  • 13
-1

You can use the function fgets to read a line from the file. Then you can use the function sscanf to count the number of numbers in the line.

For example let's assume that you already read a line from the file and store it in the array with name s

char s[] = "1 12 123 1234 12345\n";

Now in a loop you can count the number of numbers for example the following way

    size_t count = 0;
    int pos;

    for (const char *p = s; sscanf( p, "%*d%n", &pos ) != EOF; p += pos)
    {
        ++count;
    }

    printf( "count = %zu\n", count );

The output of this code snippet will be

count = 5

If you do not know the maximum size of a record in the file you can dynamically reallocate a character array until fgets will read the new line character '\n' and then apply the approach with sscanf.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I considered this solution however the array size I would need to contain the line fully is unknown and so I wasn't sure how to initialise the array – Harry Day Oct 31 '22 at 20:46
  • @HarryDay You can dynamically reallocate arrays until the new line character '\n' will be read by the function fgets. – Vlad from Moscow Oct 31 '22 at 20:51
  • could you link to a documentation or an example about this? I'm struggling to find it online, thanks – Harry Day Oct 31 '22 at 20:53
  • @HarryDay You can find in the internet the documentation by the keyword fgets. – Vlad from Moscow Oct 31 '22 at 20:54
  • You don't need an array to hold the numbers if all you're doing is counting how many there are on the line. Note that using `fscanf()` et al to find lines is ridiculously hard; using `fgets()` or POSIX `getline()` and then analyzing with `sscanf()` is a much better idea. See also [Using `sscanf()` in loops](https://stackoverflow.com/questions/3975236/how-to-use-sscanf-in-loops). – Jonathan Leffler Oct 31 '22 at 20:59