2

I've literally just started programming in C. Coming from a little understanding of Python.

Just had a lecture on C, the lecture was about this:

#include <stdio.h>

int main() {
    FILE *file;
    char name[10], degree[5];
    int mark;
    file = fopen("file.txt", "r");
    while (fscan(file("%s %s %d", name, degree, &mark) != EOF);
        printf("%s %s %d", name, degree, mark);
    fclose(file);
}

I'm specifically asking why we the lecturer would have used an array rather than just declaring two string variables. Searching for a deeper answer than just, "that's just C for you".

gsamaras
  • 71,951
  • 46
  • 188
  • 305
Florian Suess
  • 655
  • 6
  • 10
  • 1
    This code can not compile. – BLUEPIXY Sep 21 '16 at 23:30
  • There are only string literals in C. They have type char[] and are just null-terminated character arrays. See http://stackoverflow.com/questions/2245664/what-is-the-type-of-string-literals-in-c-and-c. – Mick Sep 21 '16 at 23:33
  • The line `(fscan(file("%s %s %d", name, degree, &mark) != EOF);` contains several mistakes, please check your transcription – M.M Sep 21 '16 at 23:34
  • Answers below cover your question, but to augment them, higher level languages (Python, Java, C#, C++, ...) use char arrays to represent their strings internally, but that is made invisible to you. – Cody Sep 21 '16 at 23:49
  • 2
    @MickSharpe: There are string literals in C source code. A string literal is a syntactic construct delimited by double-quote characters. C certainly does have strings, but a string is a data format, not a data type. It is by definition "a contiguous sequence of characters terminated by and including the first null character". – Keith Thompson Sep 22 '16 at 00:04
  • @MickSharpe C _strings_ as deifned in the standard library are a sub-set of _string literals. E. g. `"abc\0xyx"` is an 8 character _string literal_ but not an 8 character _string_. – chux - Reinstate Monica Sep 22 '16 at 01:06

3 Answers3

3

There are multiple typos on this line:

while (fscan(file("%s %s %d", name, degree, &mark) != EOF);
    printf("%s %s %d", name, degree, mark);

It should read:

while (fscanf(file, "%s %s %d", name, degree, &mark) == 3)
    printf("%s %s %d", name, degree, mark);

Can you spot the 4 mistakes?

  • The function is called fscanf
  • file is an argument followed by ,, not a function name followed by (
  • you should keep looping for as long as fscanf converts 3 values. If conversion fails, for example because the third field is not a number, it will return a short count, not necessarily EOF.
  • you typed an extra ; after the condition. This is parsed as an empty statement: the loop keeps reading until end of file, doing nothing, and finally executes printf just once, with potentially invalid arguments.

The programmer uses char arrays and passes their address to fscanf. If he had used pointers (char *), he would have needed to allocate memory to make them point to something and pass their values to fscanf, a different approach that is not needed for fixed array sizes.

Note that the code should prevent potential buffer overflows by specifying the maximum number of characters to store into the arrays:

while (fscanf(file, "%9s %4s %d", name, degree, &mark) == 3) {
    printf("%s %s %d", name, degree, mark);
}

Note also that these hard-coded numbers must match the array sizes minus 1, an there is no direct way to pass the array sizes to fscanf(), a common source of bugs when the code is modified. This function has many quirks and shortcomings, use with extreme care.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
1

Take name[] for example. It's an array of chars, a collection of chars if you like.

There is no string type in , so we use an array an array of chars when we want to use a string.

The code is written as such, so that we can read the actual string in a line of the file, in our array.


As a side note, this program will produce syntax errors.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
0

What you have in every non-empty file is a series of bytes. Therefor, what your C program has to do is read bytes. Since the variable type char is used to represent a byte, and since you want to read multiple bytes at once for efficiency purposes, you read an array of chars. That's for the general understanding of what reading from a file means.

Going back to your example, there is no string type in C. A string is an array of bytes (char[]) ended by a nul character. What the lecturer is doing is:

  1. define an array of chars (which will contain a string) => char name[10] is an array that may contain a string of at most 9 characters (the last byte would be used for '\0').
  2. ask fscanf to read a string, which means it will read multiple bytes (multiple chars) until it finds a nul character ('\0') and put all of that in the given array.

To understand what's happening, forget about string as an opaque data type (which might be true in other programming languages) and see them as what they really are: arrays of chars.

yoones
  • 2,394
  • 1
  • 16
  • 20