tags:

views:

198

answers:

4

How can you count the number of characters or numbers in each line? Is there something like a EOF thats more like a End of Line?

+2  A: 

Regarding reading a file line by line, look at fgets.

char *fgets(char *restrict s, int n, FILE *restrict stream);

The fgets() function shall read bytes from stream into the array pointed to by s, until n-1 bytes are read, or a is read and transferred to s, or an end-of-file condition is encountered. The string is then terminated with a null byte.

The only problem here may be if you can't guarantee a maximum line size in your file. If that is the case, you can iterate over characters until you see a line feed.

Regarding end of line:

Short answer: \n is the newline character (also called a line feed).

Long answer, from Wikipedia:

Systems based on ASCII or a compatible character set use either LF (Line feed, 0x0A, 10 in decimal) or CR (Carriage return, 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A); see below for the historical reason for the CR+LF convention. These characters are based on printer commands: The line feed indicated that one line of paper should feed out of the printer, and a carriage return indicated that the printer carriage should return to the beginning of the current line.

* LF:    Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
* CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
* CR:    Commodore 8-bit machines, Apple II family, Mac OS up to version 9 and OS-9

But since you are not likely to be working with a representation that uses carriage return only, looking for a line feed should be fine.

danben
soo you can make a loop until char = \n
MRP
Right [15 chars]
danben
FILE *in;in = fopen ( "numbers.txt", "r" ); if ( in != NULL ) {Do I use a fget until \n ?
MRP
Right, it would be fgetc to get a single character.
danben
Ok ill give it a try.
MRP
@danben: if the file is open in text mode, the underlying library will take care of representing newlines as `'\n'` only, even on windows.
Alok
+1  A: 

You can iterate through each character in the line and keep incrementing a counter until the end-of-line ('\n') is encountered. Make sure to open the file in text mode ("r") and not binary mode ("rb"). Otherwise the stream won't automatically convert different platforms' line ending sequences into '\n' characters.

Here is an example:

int charcount( FILE *const fin )
{
    int c, count;

    count = 0;
    for( ;; )
    {
        c = fgetc( fin );
        if( c == EOF || c == '\n' )
            break;
        ++count;
    }

    return count;
}

Here's an example program to test the above function:

#include <stdio.h>

int main( int argc, char **argv )
{
    FILE *fin;

    fin = fopen( "test.txt", "r" );
    if( fin == NULL )
        return 1;

    printf( "Character count: %d.\n", charcount( fin ) );

    fclose( fin );
    return 0;
}
Sam
You don't really need to go character-by-character to get the index of the new line. You can use strcspn() to find the index of the '\n'. (See http://stackoverflow.com/questions/4824/string-indexof-function-in-c)
David
strcspn() and strspn() do not read from files. To use them, you would have to read the entire line into a string and then re-iterate through it to find the '\n' character. This is less efficient. Of course, it depends on how MRP is doing his file IO code.
Sam
Yes, this code does help although I had to change somethings around. But I have a better understanding how this works.. Thank you
MRP
I actually didnt use your second code to test it.
MRP
You're welcome, and I'm glad I could help.
Sam
+1  A: 

\n is the newline character in C. In other languages, such as C#, you may use something like C#'s Environment.EndLine to overcome platform difficulties.

If you already know that your string is one line (let's call it line), use strlen(line) to get the number of characters in it. Subtract 1 if it ends with the '\n'.

If the string has new line characters in it, you'll need to split it around the new line characters and then call strlen() on each substring.

David
He doesn't have a string, he has a file.
danben
+1  A: 

If you open a file in text mode, i.e., without a b in the second argument to fopen(), you can read characters one-by-one until you hit a '\n' to determine the line size. The underlying system should take care of translating the end of line terminators to just one character, '\n'. The last line of a text file, on some systems, may not end with a '\n', so that is a special case.

Pseudocode:

count := 0
c := next()
while c != EOF and c != '\n'"
    count := count + 1

the above will count the number of characters in a given line. next() is a function to return the next character from your file.

Alternatively, you can use fgets() with a buffer:

char buf[SIZE];
count = 0;
while (fgets(buf, sizeof buf, fp) != NULL) {
    /* see if the string represented by buf has a '\n' in it,
       if yes, add the index of that '\n' to count, and that's
       the number of characters on that line, which you can
       return to the caller.  If not, add sizeof buf - 1 to count */
}
/* If count is non-zero here, the last line ended without a newline */
Alok
Can you explain SIZE.. Im not sure if that is a Var or a command C uses.
MRP
@MRP: `SIZE` is a convenient positive integral value, either a pre-processor macro or a magic number. I didn't give you a full code since I am not sure if it's a homework question. :-)
Alok
Well if SIZE is a number I put in.. what I need it for wont work then since i don't know the size..
MRP
For instance in one line it could be 10 ints or 20 ints
MRP
No, let's say `SIZE` is 128. Then, as my comment after `fgets()` says, if the string represented by `buf` doesn't contain a newline, it means your line was longer than 127 characters. In which case, you call `fgets()` again, and increment `count` by 127. So, the code above will read long lines without a problem, and correctly determine the number of characters in a line.
Alok